这与 How to use gmock to test that a class calls it's base class' methods 密切相关但我正在努力让这个与我的示例一起工作。
我正在使用 GTest 和 GMock 来测试新功能,因此我有一个基类...
class SimpleObject
{
public:
explicit SimpleObject() {}
virtual void moveX(int dX)
{
// Do important stuff like updating position, bounding box etc.
}
// ...
};
基于其他 TDD,我有一个派生类,新功能是当我在派生对象上调用 moveX 时,它会执行一些特定操作,但它还需要执行 SimpleObject::moveX 中的重要操作。
我已经有与 SimpleObject::moveX 函数相关的测试驱动单元测试,因此我不想为派生类重复它们。只要我知道 SimpleObject::moveX 被调用,那么一切都很好。
无论如何,根据上面的链接和遵循 TDD,我最终得到了以下结果。
派生类:
class ComplexObject : public SimpleObject
{
public:
virtual void moveX(int dX)
{
// Do something specific
}
};
“可测试”类:
class TestableComplexObject : public ComplexObject
{
public:
MOCK_METHOD1(moveX, void(int dX));
void doMoveX(int dX)
{
SimpleObject::moveX(dX);
}
};
测试:
TEST_F(ATestableComplexObject, CallsBaseClassMoveXWhenMoveXIsCalled)
{
int dX(8);
TestableComplexObject obj;
EXPECT_CALL(obj, moveX(dX))
.Times(1)
.WillRepeatedly(testing::Invoke(&obj, &TestableComplexObject::doMoveX));
obj.moveX(dX);
}
如果我运行测试,那么一切都会通过。这是不正确的,因为正如您所看到的 ComplexObject::moveX 没有执行任何操作。
此外,无论我在 doMoveX 中输入什么(我认为这是为了设定我的期望),测试仍然会通过。
我显然在这里缺少一些简单的东西,所以有什么想法吗?
最佳答案
感谢您的评论,通过对设计进行调整,我能够测试我想要的内容。
首先,为SimpleObject创建一个接口(interface):
class ISimpleObject
{
public:
virtual void moveX(int dX) = 0;
};
我的 SimpleObject 类然后实现这个:
class SimpleObject : public ISimpleObject
{
public:
explicit SimpleObject() {}
virtual void moveX(int dX)
{
(void) dX;
// Do important stuff like updating position, bounding box etc.
}
};
ComplexObject 不是从 SimpleObject 继承,而是从接口(interface)继承并拥有一个 SimpleObject(即它“有一个”而不是“是一个”)。构造函数确保我们传入一个 SimpleObject,正是这种注入(inject)使模拟变得更容易。
class ComplexObject : public ISimpleObject
{
public:
ComplexObject(SimpleObject *obj)
{
_obj = obj;
}
virtual void moveX(int dX)
{
_obj->moveX(dX);
}
private:
SimpleObject *_obj;
};
现在我只是从 SimpleObject 模拟我感兴趣的调用
class SimpleObjectMock : public SimpleObject
{
public:
MOCK_METHOD1(moveX, void(int dX));
// Do important stuff like updating position, bounding box etc.
};
测试也被简化
TEST_F(AComplexObject, CallsBaseClassMoveXWhenMoveX)
{
int dX(8);
SimpleObjectMock mock;
ComplexObject obj(&mock);
EXPECT_CALL(mock, moveX(dX)).Times(1);
obj.moveX(dX);
}
行为符合预期。如果 ComplexObject::moveX 函数为空(因为它在开始时就是空的),则测试失败。仅当您调用 SimpleObject::moveX 时它才会通过。
关于c++ - 如何使用GMock检查基类函数被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37908217/