【问题标题】:How to use Google mock on legacy code如何在遗留代码上使用 Google mock
【发布时间】:2014-07-01 08:38:58
【问题描述】:

我有大量遗留代码,我不应该对现有代码进行任何更改。现在,如果我必须对使用该类的指针及其非虚拟方法调用另一个类的方法(例如Class B)的类(例如class A)执行单元测试。如何使用google mock 模拟Class B 的方法?

我已通过以下方式阅读了执行此操作的方法:
1. 虚拟化;
2. 使用模板。

但我对更改现有遗留代码不感兴趣。

提前致谢!

【问题讨论】:

标签: googlemock


【解决方案1】:

以下是您可能开始学习的两个课程:

您要对其执行单元测试的类:

class A {
public:
    int do_a_work(B * bPtr) {
        std::cout << "-- in a::do_a_work ---" << std::endl;
        return 1 + bPtr->do_b_work();
    }
};

你不能修改的类:

// Class that we are *NOT* going to modify
class B {
public:
    int do_b_work() {
        std::cout << "-- in b::do_b_work ---" << std::endl;
        return 2;
    }
};

您的生产(非测试)代码。

A a;
B b; 
a.do_a_work(&b); // b->do_b_work will be called ... 

解决方案 1. 使用 Cookbook for Mocking Nonvirtual Methods 中描述的模板。

更新 A 类以使用模板。

template <class B_class> 
class A {
public:
    int do_a_work(B_class * bPtr) {
        std::cout << "-- in a::do_a_work ---" << std::endl;
        return 1 + bPtr->do_b_work();
    }
};

在生产代码中,使用真正的 B 类。

A<B> aObj;
B bObj;
std::cout << aObj.do_a_work(&bObj) << std::endl;

在测试代码中,使用模拟的 B 类。

// Mock class. 
// It doesn't inherit from B. 
class B_Mock {
public:
    MOCK_METHOD0(do_b_work, int());
};

在测试代码中调用模拟类:

// Use the mocked class 
B_Mock b;
A<B_Mock> a;
a.do_a_work(); // this will use the B_Mock->do_b_work MOCK_METHOD0.

解决方案 2. 将不想修改的类包装在容器中。

创建一个包含您不想修改的类的实例的新类。

// Add B Container class 
class B_Container : public B{
private:
    B my_b;
public:
    B_Container() {}
    // Make all public functions virtual (so that we can mock them out)
    virtual int do_b_work() {  
        // Forward all work to B
        return my_b.do_b_work();
    }
    // repeat for all other public functions ...
};

然后,修改类 A 以使用 B_container 而不是 B。

class A {
public:
    int do_a_work(B_Container * bPtr) {
        std::cout << "-- in a::do_a_work ---" << std::endl;
        return 1 + bPtr->do_b_work();
    }
};

在生产中,您的代码如下所示:

A a;
B_Container b;  // This was just "B b;"
a.do_a_work(&b);

既然 B_Container 有一个虚函数,您可以像这样模拟调用:

class B_Mock : public B_Container{
public:
    MOCK_METHOD0(do_b_work, int());
};

在测试代码中,你可以这样做:

B_Mock b;
A a;
a.do_a_work(); // This will call B_Mock->do_b_work, which inherits from B_Container

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多