如何在 Google Mock 中访问私有成员

Dav*_*vid 5 c++ unit-testing mocking googlemock

我正在尝试为具有私有向量的类编写一个模拟,该类会将数据插入到私有向量中。但是,我没有找到使用 Google Mock 来做到这一点的方法。理想情况下,我希望界面中没有任何与测试相关的内容。另外,我不想使私有向量受到保护并对该类进行子类化并添加访问器方法,因为这会导致我的代码泄漏其实现。

这是我到目前为止所拥有的。我想要完成的是使用 Fake 类插入数据,并使用 Mock 类在指向 Fake 类的指针上调用 Real::first() (这样我就可以使用 Fake 的向量而不是 Real 的向量)。编译该程序时,返回 -1 而不是 4。

#include <iostream>
#include <vector>
#include <gmock/gmock.h>

using namespace std;
//using ::testing::_;
using ::testing::Invoke;

class A {
protected:
    vector<int> a;

public:
    virtual int first() = 0;
    virtual ~A() {}
};

class Real : public A {
public:
    virtual int first() {
        cout << "size: " << a.size() << endl;
        return a[0];
    }
};

class Fake : public A {
public:
    virtual void insert(int b) {
        a.push_back(b);
        cout << a.size() << endl;
    }

private:
    virtual int first() { return -1; }
};

class Mock : public A {
public:
    Mock(Fake* c) :
        c_(c) {}

    MOCK_METHOD0(first, int());

    void delegate() {
        ON_CALL(*this, first())
            .WillByDefault(Invoke((Real*)c_, &Real::first));
    }

private:
    Fake* c_;
};

int main(void) {
    Fake c;
    c.insert(4);

    Mock z(&c);

    z.delegate();

    cout << z.first() << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有谁知道我做错了什么?或者有更简单的方法来完成这个任务吗?

Hen*_*rik 2

c给出的实现实例Mock是一个Fake对象,无论对它的指针进行多少转换都不会使其成为Real. 因为 和FakeReal派生first()A,所以即使编译器认为它调用了a 的函数,该Fake对象也会被成功调用。first()first()Real

说出您想要什么并不容易,因为您的示例非常小(并且在这种最小情况下实际上并不需要模拟),但是有多种方法可以实现您想要的行为,其中有一些是最重要的我的头:

选项1

first提供in的默认定义A并从 中删除定义Fake

class A {
protected:
    vector<int> a;

public:
    virtual int first() {
        return a[0];
    }

    virtual ~A() {}
};

class Fake : public A {
public:
    virtual void insert(int b) {
        a.push_back(b);
        cout << a.size() << endl;
    }
};
Run Code Online (Sandbox Code Playgroud)

选项2

first中的工作定义Fake。我知道,我知道,这段代码不属于Fake,但它是对这种微不足道的情况的快速修复。

class Fake : public A {
public:
    virtual void insert(int b) {
        a.push_back(b);
        cout << a.size() << endl;
    }

private:
    virtual int first() {
        return a[0];
    }
};
Run Code Online (Sandbox Code Playgroud)

选项3

如果所有这些都是关于不调用A's中的打印输出first(),我建议您改为模拟输出流。