我有一种情况,我想检查是否使用参数X调用了模拟对象方法,但是测试仅获得对X的访问权限。[[after调用了模拟,因此我无法事先设置EXPECT_CALL。
例如// The class I'm testing.
class Maker
{
void register(Listener& lis);
Obj& make()
{
// make new Obj o
// call created(o) on registered Listener
// return o
}
}
class Listener
{
virtual void created(Obj& o) = 0;
}
// The test
Listener lis;
Maker maker;
maker.register(lis);
Obj& o = maker.make();
// Check that lis was invoked using param o...how?
我可以使用Google模拟吗?使用Google模拟,最优雅/可读的方法是什么?很明显,我可以制作自己的MockListener,该监听器将记录调用参数,而不是使用Google模拟。但我希望Google嘲笑会呈现出更具可读性的机制,类似于EXPECT_CALL。
SaveArg<N>
操作保存调用SaveArg<N>
的参数的值,因此您可以将其值与Listener::created(Obj&)
之后返回的值进行比较。这将要求您为类maker.make()
(即Obj
)提供相等运算符。
您的测试将如下所示:
bool operator==(const Obj&, const Obj&)
似乎是为“基于交互的测试”而不是“基于状态的测试”制作的,如class ListenerMock : public Listener
{
public:
MOCK_METHOD1(created, void(Obj&));
};
TEST(MakerTest, make_registersObject)
{
ListenerMock lis;
Maker maker;
maker.register(lis);
Obj createdArg;
EXPECT_CALL(lis, created(_))
.Times(1)
.WillOnce(SaveArg<0>(&createdArg));
Obj& o = maker.make();
ASSERT_EQ(createdArg, o);
}
所述:
使用Google Mock,您可以轻松地用C ++创建模拟。人们可能很想在任何地方使用它们。有时它们效果很好,有时您可能会发现它们很难使用。那么,在后一种情况下怎么了?[不使用模拟编写测试时,您将执行代码并声明其返回正确的值或系统处于预期状态。有时称为“基于状态的测试”。
模拟非常适合进行所谓的“基于交互”的测试:模拟对象无需检查系统状态,而是验证它们是否以正确的方式被调用并在出现错误时立即报告,从而为您提供了处理触发错误的确切上下文。与基于状态的测试相比,这样做通常更有效,更经济。
如果您要进行基于状态的测试,并使用双重测试来模拟真实对象,那么最好使用伪造品。在这种情况下使用模拟会引起痛苦,因为模拟执行复杂的动作并不是重点。如果您遇到这种情况并认为模拟很烂,那么您就没有使用正确的工具来解决问题。或者,您可能正在尝试解决错误的问题。 :-)