gmock测试的正常模式为
class MyMockClass : public MyRealClass {
/// swap out behavior of an existng method
MOCK_method(some_method .....);
}
TEST() {
MyMockClass mock;
EXPECT_CALLED(mock.some_method);
/// ******* here I have to explicitly pass in the mock obj into the system
MyConsumerClass myconsumer(mock);
myconsumer.do_something_to_trigger_mock__some_method();
}
在上面"****"我必须显式地将模拟对象传递到系统中,即将我的消费者对象与模拟对象组合在一起。但是现在我面对一个现有的消费者类impl,它的构造函数不允许传入依赖对象;事实上,我可能会说,在一个消费者类的元素中列出所有的依赖对象是不可能的;更重要的是,我的实际情况是,要测试的消费者类位于模拟对象之上的几个级别:
class MyConsumerClass {
private:
MyHelperClass helper
public:
void trigger() {
helper.trigger_again();
}
}
class MyHelperClass {
BottomClass bottom;
public:
void trigger_again() {
bottom.do_something();
}
}
class BottomClass {
public :
void do_something();
}
在这种情况下,在我们的单元测试中,我们只能实例化顶层MyConsumerClass,并且我希望验证当我调用myconsumer.trigger()时,我可以验证调用了BottomClass.do_something(),可能还验证了它是用特定参数调用的。但是上面的类层次结构是这样写的,所以我不能从顶层传入一个模拟的BottomClass对象。
在jmock或jmockit中,我记得有可能全局地消除BottomClass.do_something()的行为,而不引用特定的模拟对象,即"静态模拟",因为它们在jmockit中被称为。有可能在gmock (c++)中做类似的事情吗?由于
将注释转换为答案:
我能想到两件事:
-
你为什么不单独测试你的类呢?例如,为MyHelperClass编写一个单独的测试。
-
如果依赖注入不适合您,GMock允许您通过模板化您的类来进行静态模拟:将您的类转换为模板,然后使用用于生产的实际类和用于测试的模拟类实例化模板。请看这里的例子。
在你的情况下,你的代码可以重写成这样:
//-----------------------------------------------------------------------------
// Real classes used in production
//-----------------------------------------------------------------------------
class BottomClass {
public:
void do_something();
};
//-----------------------------------------------------------------------------
// Templatized classes used in test or production
//-----------------------------------------------------------------------------
template <class BType>
class MyHelperClass {
public:
BType bottom;
public:
void trigger_again() { bottom.do_something(); }
};
template <class BType, template <typename> class HType>
class MyConsumerClass {
public:
HType<BType> helper;
public:
void trigger() { helper.trigger_again(); }
};
//-----------------------------------------------------------------------------
// Mocked classes used in test
//-----------------------------------------------------------------------------
class MockedBottomClass {
public:
MOCK_METHOD(void, do_something, (), ());
};
TEST(BottomClassTest, Test1) {
MyConsumerClass<MockedBottomClass, MyHelperClass> mock;
EXPECT_CALL(mock.helper.bottom, do_something());
mock.trigger();
}
我必须将您的一些私有成员转换为公共成员才能使测试工作。
这里的实例:https://godbolt.org/z/qc3chdxKz