我可以使用Google模拟来检查方法参数而无需预先设置期望吗?

问题描述 投票:3回答:2

我有一种情况,我想检查是否使用参数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。

c++ unit-testing googletest googlemock
2个回答
4
投票
您可以使用SaveArg<N>操作保存调用SaveArg<N>的参数的值,因此您可以将其值与Listener::created(Obj&)之后返回的值进行比较。

这将要求您为类maker.make()(即Obj)提供相等运算符。

您的测试将如下所示:

bool operator==(const Obj&, const Obj&)


-2
投票
我认为答案是“这不是Google嘲笑的目的。”

似乎是为“基于交互的测试”而不是“基于状态的测试”制作的,如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 ++创建模拟。人们可能很想在任何地方使用它们。有时它们效果很好,有时您可能会发现它们很难使用。那么,在后一种情况下怎么了?

[不使用模拟编写测试时,您将执行代码并声明其返回正确的值或系统处于预期状态。有时称为“基于状态的测试”。

模拟非常适合进行所谓的“基于交互”的测试:模拟对象无需检查系统状态,而是验证它们是否以正确的方式被调用并在出现错误时立即报告,从而为您提供了处理触发错误的确切上下文。与基于状态的测试相比,这样做通常更有效,更经济。

如果您要进行基于状态的测试,并使用双重测试来模拟真实对象,那么最好使用伪造品。在这种情况下使用模拟会引起痛苦,因为模拟执行复杂的动作并不是重点。如果您遇到这种情况并认为模拟很烂,那么您就没有使用正确的工具来解决问题。或者,您可能正在尝试解决错误的问题。 :-)

© www.soinside.com 2019 - 2024. All rights reserved.