c++ - 如何使用GMock检查基类函数被调用

标签 c++ unit-testing tdd googletest googlemock

这与 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/

相关文章:

java - 单元测试覆盖率和测试大型组件

使用 Visual Studio 的 C++ 编译错误(LNK1120 和 LNK2019)

C++ 和 QT Creator

unit-testing - Resharper 和 Moq 返回方法

typescript - 如何在 Typescript 中测试泛型类型?不是泛型类型的实现,而是作为类型保护?

tdd - 有哪些好的服务或工具可用于远程结对编程?

c# - 我可以在 Rhino Mocks 中设置当 AssertWasCalled 失败时显示一条用户友好的消息吗?

c++ - 检查文件内容是否已实际写入磁盘 - 未在磁盘 Controller 的缓冲区中排队

c++ - 如何检测窗口当前正在运行模态对话框?

java - 如何在 zipoutputstream 中断言响应