【问题标题】:How to use mocks with a test fixture in GMock?如何在 GMock 中使用带有测试夹具的模拟?
【发布时间】:2019-11-19 18:30:22
【问题描述】:

我的测试中有一个测试夹具,因此我不必重复实例化我的类的对象,但我不确定如何使用模拟。简单来说,类是这样定义的:

class Class1 {
public:
  Class1(std::shared_ptr<Class2> class_two);
  void doThisThing() { doThatThing(); }
}

class Class2 {
public:
  Class2(Class3* class3_ptr);
  int doThatThing();
}

(类 1 使用指向类 2 的共享指针构造。类 2 使用指向类 3 的指针构造。类 1 调用函数“doThisThing”,该函数调用类 2 的函数 doThatThing。)

我需要为 doThatThing()(以及 Class2 的其余函数)创建一个模拟,但无法弄清楚如何将模拟对象传递给 Class 1。这是我目前在测试代码中的内容:

class TestClass1 : public ::testing::Test {
  TestClass1(){
//Construct instance of Class1 and store as member variable
    std::shared_ptr<Class3> class_three = std::make_shared<Class3>();
    std::shared_ptr<Class2> class_two = std::make_shared<Class2>((Class3*)class_three.get());
    class_one = new Class1(class_two);
  };
Class1* class_one;
}

MockClass2 : public Class2 {
  MOCK_METHOD0(doThatThing, int());
}

TEST_F(TestClass1, doThatThingTest){
  MockClass2 mockObj;

**THIS IS WHERE I'M STUCK. How do I get that mockObj into my TestClass1 Fixture? As of now, it is calling the actual function, not the mock***

  class_one->doThatThing();
  EXPECT_CALL(mockObj, doThatThing());
}

我必须对实际代码进行抽象和简化,所以我希望以上内容有意义。

【问题讨论】:

  • Google mock 没有魔法(唉!),当它最初不是这样的时候,它不能做多态的东西。您需要在原始代码中使用虚拟函数或模板才能模拟它。

标签: c++ googletest googlemock


【解决方案1】:

假设您的 MockClass2 有效,您应该尝试以下操作:

在这里,您应该覆盖在每次调用测试函数之前调用的函数SetUp 以准备测试数据。并覆盖每次调用测试函数后调用的TearDown 以清理测试数据。

struct TestClass1 : public ::testing::Test
{
    void SetUp() override
    {
        class_two_mock = std::make_shared<MockClass2>();
        class_one = std::make_unique<Class1>(class_two_mock);        
    }
    void TearDown() override
    {
        class_one.reset();
        class_two_mock.reset();
    }

    std::shared_ptr<MockClass2> class_two_mock
    std::unique_ptr<Class1> class_one;
};

在测试函数中,您必须在执行某些操作之前声明您的期望。

TEST_F(TestClass1, doThatThingTest)
{
    EXPECT_CALL(*class_two_mock, doThatThing());

    class_one->doThatThing();
}

您可能需要Class2 的接口。这里的代码没有经过测试。

【讨论】:

  • 关闭....但不太好用。由于 Class2 没有默认构造函数,因此 MockClass2 的默认构造函数被隐式删除,这使得该行抛出错误:class_two_mock = std::make_shared&lt;MockClass2&gt;(); 我尝试添加 MockClass2(){};但收到我需要显式初始化 Class2 的错误。添加了` Class3* class3_ptr = new Class3(); Class2(class3_ptr); ` 和它的说法“使用不同类型的 Class2 和 Class3* 重新定义 class3_ptr”??
  • 是的,这就是为什么我建议使用Class2的接口。
  • 这是唯一的选择吗?我想避免编辑源代码。
  • 正如 Valeriy Savchenko 在他的评论中提到的那样,这似乎是不可能的。
  • 顺便说一句,假设您的测试正确但失败,那么您不会修复类/代码?如果是这样,测试是不必要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
相关资源
最近更新 更多