我正在尝试为具有私有向量的类编写模拟,该向量将数据插入到私有向量中。但是,我没有看到使用Google Mock的方法。理想情况下,我想在我的界面中没有与测试相关的任何内容。此外,我不想使私有向量受保护并对类进行子类化并添加一个访问器方法,因为这会导致我的代码泄漏其实现。
这是我到目前为止所拥有的。我想要完成的是使用Fake类插入数据,并使用Mock类在指向Fake类的指针上调用Real :: first()以便我可以使用Fake' s矢量而不是真实的。编译此程序时,返回-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;
}
有谁知道我做错了什么?或者有更简单的方法来实现这一目标吗?
答案 0 :(得分:1)
赋予c
的实现实例Mock
是一个Fake
对象,并且指向它的指针的数量不会变为Real
。由于Fake
和Real
都从first()
派生A
,即使编译器认为Fake
对象first()
已成功调用它调用first()
的{{1}}函数。
说出你想要的东西并不是那么容易,因为你的例子是如此之小(在最小的情况下,嘲弄并不是真的必要),但是有很多方法可以实现你理想的行为,有些偏离我的头脑:
在Real
中提供first
的默认定义,并从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;
}
};
中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];
}
};
A
中调用打印输出,我建议你嘲笑出去。
答案 1 :(得分:0)
这有点突破了第一个要求,但为使测试工作而添加的样板数量很少。
将存储与A和模拟分离到它自己的类中,并将其注入构造函数中。
class AStorage {
vector<int> vals;
};
class A {
AStorage& storage;
public:
A(AStorage& stor) :
storage(stor) {}
};
不幸的是,A不能拥有自己的存储空间。但是,测试现在更容易,因为测试将引用存储对象,允许它在幕后数据后面进行更改。