使用googlemock模拟非虚拟函数
Using googlemock with fake impls of non-virtual functions
我有一些基于googlemock框架的单元测试遗留代码。当我试图用一些新的场景扩展单元测试时,我遇到了以下问题:
class D
{
public:
void pubMethod1();
int pubMethod2();
// There are pretty much non-virtual methods, both public and private
...
protected:
uint method3();
void method4();
...
// Some class members are here
};
class SUT
{
public:
...
protected:
D _dep;
};
应该测试SUT类(待测软件),其实现在文件sut.cpp
中定义。SUT依赖于D类,其实现在文件d.cpp
中。为了减少链接器依赖关系,我不想将d.cpp
添加到测试中,因此当我链接测试时,对D的成员有许多"未定义符号"错误。为了消除错误并提供可预测的行为,我将在测试中为D的方法创建假实现。然而,我仍然不能使用它与所有的googlemock的力量,直到D的方法是虚拟的。
我喜欢使用来自googlemock框架的WillOnce, AtLeast, willrepeat, Invoke等函数,因为它使单元测试创建更容易。问题是我不喜欢改变D的接口,把它的方法变成虚拟方法的想法。是否有可能使用googlemock函数与假实现我要为D的方法创建?
注意:我已经考虑了模板SUT类的解决方案,但是我想知道是否存在其他解决方案。
首先,最好是重新设计SUT类,让D通过一些抽象接口注入。因为我下面描述的解决方法真的很棘手——所以在将来不太容易维护和理解……
如果你打算在UT目标中实现你的D类,那么你可以为D: DMock
制作Mock类。这个DMock
与D
没有关系——不是从它派生出来的——但它需要与真实/虚假的D对象配对。
所以-看这个例子:
创建DMock——模仿D接口(注意您应该只模仿公共函数——因为您的SUT只使用公共函数):
class DMock
{
public:
MOCK_METHOD0(pubMethod1, void ());
MOCK_METHOD0(pubMethod2, int ());
};
将真实的(但假的)D对象与DMock对象配对-像这样:
class DMockRepo
{
public:
// for UT
void addMockToUse(DMock* dMock) { freeMock.push_back(dMock); }
// for implementing D fake methods
DMock& getMock(D* original)
{
// TODO: use more sophisticated way to add mock to map...
if (not usedMock[original])
{
usedMock[original] = freeMock.front();
freeMock.pop_front();
}
return *useddMock[original];
}
static DMockRepo& getInstance() { return instance; } //singleton
private:
DMockRepo() {} // private
static DMockRepo instance;
std::map<D*,DMock*> usedMock;
std::deque<DMock*> freeMock;
};
使用mock创建D类的公共方法的伪实现:
void D::pubMethod1()
{
DMockRepo::getInstance().getMock(this).pubMethod1();
}
//
非公共方法是不相关的-所以做你喜欢的…
并使用DMockRepo来设置D对象的期望:
TEST(Usage,Example)
{
DMock dMock;
DMockRepo::getInstance().addMockToUse(&dMock);
SUT sut; // you should know how many D objects SUT needs - I assume just one
EXPECT_CALL(dMock, pubMethod1());
sut.doSomethingThatCallsDpubMethod1();
}
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 类型擦除的std::function与虚拟函数调用的开销
- 重写虚拟函数和继承
- 用纯虚拟函数兜圈子
- 为什么使用存储在虚拟方法表中的地址调用虚拟函数的函数会返回垃圾?
- 禁止子函数调用父级的抽象(或虚拟)函数
- 无法在子类中使用虚拟函数C++
- 无法在派生对象上运行虚拟函数
- 我可以调用从 main() 覆盖的虚拟函数吗?
- 在 C++ 中将函数获取和设置为虚拟函数
- 使用在堆栈上创建的对象调用虚拟函数
- 为什么在这种情况下不调用我的虚拟函数实现?
- 在C++中使虚拟函数私有化
- 模板继承类中的虚拟函数
- 为什么构造函数的虚拟函数调用有时有效,但其他调用却无效
- doxygenc++虚拟函数和实现
- 如何从派生类函数中调用虚拟函数