c++11 - C++ 中的模拟静态方法

标签 c++11 googletest googlemock

我刚刚开始使用 googleTest 进行单元测试。 我遇到一种情况,一个类的静态方法正在另一个类中调用

class A {
  public:
   static bool retriveJsonData(std::string name, Json::Value& responseJsonData);
}

在其他类中,我使用 A 类 retriveJsonData 方法。

class B {
   public:
     bool Method1 (std::string name) {
        Json::Value sampleJsonData;
        return A::retriveJsonData(name, sampleJsonData);
 }

A类的Mocking

class MockA : public A {
  public:
    MOCK_MEHTOD2(retriveJsonData, bool(std::string, Json::Value));

}

现在我必须使用 EXPECT_CALL 在 B 类的 Method2 测试中模拟 retriveJsonData。

请帮我解决如何测试这种情况?

最佳答案

Google Mock 的模拟类型提供了检查非静态成员函数的预期调用的方法,其中虚拟函数多态性或模板可以用作“接缝”,将模拟函数替换为实际函数。如果您可以设计或重构所有内容以使用其中一种技术,那就太好了。但有时,在困惑的遗留代码或使用外部库的代码等中让事情以这种方式工作会很麻烦。

在这种情况下,另一种选择是定义一个不是非静态成员函数(因此要么是自由函数要么是静态成员)的依赖函数来重定向到某个单例模拟对象。假设我们有一些翻译单元(B.cpp)要进行单元测试,并且它调用该翻译单元中未定义的一些非成员或静态成员函数(A::retrieveJsonData)。

通常,为了对 B.cpp 进行单元测试,我们会记下其所需的链接器符号,并为它们提供虚假定义,将其 stub ,只是为了将目标文件 B.o 链接到单元测试程序中:

// Fake definition:
bool A::retrieveJsonData(std::string, Json::Value&)
{ return false; }

在这种情况下,我们不想要那个假定义;我们稍后将定义它以重定向到模拟对象。

从专门针对有问题的函数调用的模拟类开始。如果还有其他非静态成员函数以普通方式测试,则该类与这些类不同。 (如果多个函数需要这一点,则这些模拟类可以针对每个函数、每个类和/或一个自由函数、每个库、一个用于所有内容来完成;但是您想如何设置它。)

class Mock_A_Static {
public:
    Mock_A_Static() {
        EXPECT_EQ(instance, nullptr);
        instance = this;
    }
    ~Mock_A_Static() {
        EXPECT_EQ(instance, this);
        instance = nullptr;
    }

    MOCK_METHOD2(retrieveJsonData, bool(std::string, Json::Value&));

private:
    static Mock_A_Static* instance;
    friend class A;
};
Mock_A_Static* Mock_A_Static::instance = nullptr;

// The function code in B.cpp will actually be directly calling:
bool A::retrieveJsonData(std::string name, Json::Value& responseJsonData)
{
    EXPECT_NE(Mock_A_Static::instance, nullptr)
        << "Mock_A_Static function called but not set up";
    if (!Mock_A_Static::instance) return false;
    return Mock_A_Static::instance->retrieveJsonData(name, responseJsonData);
}

然后只需将该类型的对象放在测试本地或固定装置类中即可。 (不过一次只能一个!)

TEST(BTest, Method1GetsJson)
{
    Mock_A_Static a_static;
    B b;
    EXPECT_CALL(a_static, retrieveJsonData(StrEq("data_x"), _));
    b.Method1("data_x");
}

关于c++11 - C++ 中的模拟静态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61227916/

相关文章:

linux - 如何在没有 root 访问权限的情况下在 Ubuntu 上安装 Google Test?

c++ - MOCK_METHOD 名称后面必须跟 '::' 必须是类或命名空间名称

C++11:可变同质非 POD 模板函数参数?

c++ - 使用 copy-and-swap 习语实现的 move 构造函数和赋值运算符

c++ - 如何在 gtest 中测试 setter 方法?

c++ - 比较 Google Test 或 Google Mock 中的特征矩阵

c++ - 将c++单元测试/模拟框架集成到Visual Studio 2012中

c++11 - 使用 c++11 枚举类时数组的大小具有非整数类型

c++ - 通过引用转换谓词返回局部变量

eclipse - 在Eclipse控制台中为Google C++测试框架中的输出文本着色文本