c++ - 如何使用 gMock 创建模拟对象?

标签 c++ unit-testing googletest googlemock

所以我正在尝试学习如何编写单元测试,但我偶然发现了这个问题,我不明白如何创建模拟对象。这是我的例子: 我有这个类:

class FooChild
{
public:
    void doThis();
    bool doThat(int n, double x);
};

这是我要测试的另一个类中的一个方法:

#include "FooFighter.h"
#include "FooChild.h"

void FooFighter::doSomething()
{
    FooChild fooChild;
    fooChild.doThis();
    fooChild.doThat(4, 5);
}

我想测试它是否调用了该方法以及调用了多少次。 谷歌模拟纪录片说,只能模拟具有虚拟方法的抽象类。这就是为什么我尝试创建 FooChild 的父类,如下所示:

class Foo
{
public:
    virtual void doThis() = 0;
    virtual bool doThat(int n, double x) = 0;
};

然后像这样创建一个模拟的 Foo 类:

#include "gmock/gmock.h"

class MockFoo : public Foo
{
public:
    MOCK_METHOD(void, doThis, (), (override));
    MOCK_METHOD(bool, doThat, (int n, double x), (override));
};

然后我尝试为 doSomething 编写测试:

TEST_F(FooFighterTest, doSomethingTest)
{
    MockFoo mock_foo
    mock_foo.doThis()
        .Times(1);
}

显然这行不通,我觉得我完全误解了 mocks 的工作原理,但我似乎找不到关于如何创建 mocks 的简单明了的解释。任何帮助或建议都会很棒。此外,我关于如何测试这样的 void 函数的方法可能是完全错误的,因此关于如何测试不返回任何内容的函数的任何建议也将是很好的。

最佳答案

您的示例离工作不远。您可能会发现阅读 gMock for Dummies 很有帮助文档。它很好地概述了基础知识。

本质上,模拟允许您对它们设定期望,并验证期望是否得到满足。您还可以执行诸如控制模拟方法的返回值之类的操作。模拟方法必须是虚拟的,但不要求它们是抽象的。

class FooChild
{
public:
    virtual void doThis() {}
    virtual bool doThat(int n, double x) { return false; }
};

class MockFooChild : public FooChild
{
public:
    MOCK_METHOD(void, doThis, (), (override));
    MOCK_METHOD(bool, doThat, (int n, double x), (override));
};

您的示例中最大的问题是 FooFighter::doSomething 使用的是具体(实际)类 FooChild。您将需要一种方法将具体类替换为模拟类(使用某种形式的依赖注入(inject))。这是一个简单的例子:

class FooFighter
{
public:
    void doSomething(FooChild &fooChild)
    {
        fooChild.doThis();
        fooChild.doThat(4, 5);
    }
};

现在您可以测试 FooFighter::doSomething 是否正在执行预期的操作:

TEST(FooFighterTest, doSomethingTest)
{
    MockFooChild mockFooChild;
    FooFighter fooFighter;

    // doThis() must be called exactly 1 time.
    EXPECT_CALL(mockFooChild, doThis).Times(Exactly(1));

    // doThat() must be called exactly 1 time with parameters 4,5
    EXPECT_CALL(mockFooChild, doThat(4,5)).Times(Exactly(1));

    fooFighter.doSomething(mockFooChild);
}

关于c++ - 如何使用 gMock 创建模拟对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60521274/

相关文章:

c++ - 如何使用 googletest/googlemock 框架测试连续/相关的更改?

c++ - 如何遍历 C++ 中的 unicode 字符?

c# - 如何对硬件性能计数器进行编程

c++ - 为什么 `std::is_const_v` 没有按预期运行?

ios - 是否可以使用 OCMock stub NSProcessInfo ?

c++ - TDD:给定 C++ 中的未定义行为,确定性地测试成员初始化

c++ - 即使在宏替换后也无法解析变量

c++ - 可以从外部访问私有(private)运营商吗?

c# - Visual Studio 单元测试在 TFS 构建上运行速度较慢

unit-testing - 单元测试流畅的 NHibernate。需要帮助理解测试期间发生的异常