依赖注入的好处之一是易于测试,因为可以注入模拟类。 Clazz为此使用原始指针,并将其移动到唯一指针,以表示它拥有InjectedObj对象:
Clazz::Clazz(InjectedObj *injectedObj) : injectedObjPtr(injectedObj) { }
其中injectedObjPtr
是成员:
std::unique_ptr<InjectedObj> injectedObjPtr;
doSth方法通过调用智能指针来调用executeSth:
//doSth method
int CLazz::doSth() {
return injectedObjPtr->executeSth();
}
我想通过对注入对象设置一些期望来测试Clazz, 所以我的测试看起来与此类似:
TEST_F(testFixture, exeuteTest)
{
//before
InjectedObj* injectedObj = new InjectedObj();
EXPECT_CALL(*injectedObj, executeSth())
.Times(1)
.WillOnce(Return(100));
//when
Clazz clazz(injectedObj);
//then
ASSERT_DOUBLE_EQ(clazz->doSth(), 100);
}
因此,在这种简化的情况下,clazz->doSth()
正在调用injectedObj->executeSth
,它应返回100,但其行为就像我永远不会设置期望值并始终为0。指针:injectedObj->executeSth
返回100,但使用unique_ptr调用时不会返回。当模拟指针由智能指针管理时,是否有任何方法告诉gmock设置正确的期望值?谢谢
答案 0 :(得分:0)
给定:
struct InjectedObj {
MOCK_METHOD0(executeSth, int());
};
struct Clazz {
Clazz(InjectedObj* injectedObj)
: injectedObjPtr(injectedObj) {}
int doSth() {
return injectedObjPtr->executeSth();
}
std::unique_ptr<InjectedObj> injectedObjPtr;
};
TEST(testFixture, exeuteTest) {
// before
InjectedObj* injectedObj = new InjectedObj();
EXPECT_CALL(*injectedObj, executeSth()).Times(1).WillOnce(testing::Return(100));
// when
Clazz clazz(injectedObj);
// then
ASSERT_DOUBLE_EQ(clazz.doSth(), 100);
}
我得到了:
[----------] 1 test from testFixture
[ RUN ] testFixture.exeuteTest
[ OK ] testFixture.exeuteTest (0 ms)
[----------] 1 test from testFixture (0 ms total)
我敢打赌:您忘记在基类中为 executeSth
标记 InjectedObj
一个 virtual
方法。这样,gmock 生成的 gmock_executeSth
方法是您设置的期望值,但在测试 executeSth
中使用了基类(没有动态分派),因此测试失败。
// Example, bad
// THE executeSth METHOD SHALL BE MARKED WITH virtual!!!!!
struct InjectedObj {
virtual ~InjectedObj() = default;
int executeSth() {
return 0;
}
};
struct InjectedObjMock : public InjectedObj {
MOCK_METHOD0(executeSth, int());
};
struct Clazz {
Clazz(InjectedObj* injectedObj)
: injectedObjPtr(injectedObj) {}
int doSth() {
return injectedObjPtr->executeSth();
}
std::unique_ptr<InjectedObj> injectedObjPtr;
};
TEST(testFixture, exeuteTest) {
// before
InjectedObjMock* injectedObj = new InjectedObjMock();
EXPECT_CALL(*injectedObj, executeSth()).Times(1).WillOnce(testing::Return(100));
// when
Clazz clazz(injectedObj);
// then
ASSERT_DOUBLE_EQ(clazz.doSth(), 100);
}
输出:
[ RUN ] testFixture.exeuteTest
/home/dchrzanowski/gitrepos/priv/gtestgmock/so.cpp:41: Failure
Expected: clazz.doSth()
Which is: 0
To be equal to: 100
/home/dchrzanowski/gitrepos/priv/gtestgmock/so.cpp:35: Failure
Actual function call count doesn't match EXPECT_CALL(*injectedObj, executeSth())...
Expected: to be called once
Actual: never called - unsatisfied and active
[ FAILED ] testFixture.exeuteTest (0 ms)
[----------] 1 test from testFixture (0 ms total)
避免这种情况的最佳方法:始终使基类成为纯虚拟接口。