【发布时间】:2019-01-09 23:08:49
【问题描述】:
我正在开发一个旧的大型 C++ 代码库,并且一直在为缺少它们的组件创建单元测试。
为了测试目的模拟这些类的功能的正确方法是什么?目前我正在使用虚函数,在我的测试模块中,我从基础“生产”类派生一个模拟类,并根据需要覆盖功能。
这是一个例子:
生产.cpp
class Production {
protected:
int Servers = 0;
public:
virtual bool IsValInRegistry(const std::string& regVal);
};
bool Production::IsValInRegistry(const std::string& regVal)
{
HRESULT hr = GOOD;
hr = WinSysCallToRegistry(regVal);
if (HR)
return true;
else
return false;
}
模拟.cpp
class Mock : public Production {
public:
bool IsValInRegistry(const std::string& regVal) override final;
};
Mock::IsValInRegistry(const std::string& regVal)
{
return true;
}
这是正确的前进方式吗?我担心如果我引入太多 virtual 函数,我可能会看到我想避免的性能下降。如果这个virutal模型不理想,有什么好的方法?
【问题讨论】:
-
我只做过Java,但是你知道依赖注入是怎么工作的吗?
-
在现有的大型遗留代码库中,重构代码以使用依赖注入本身就是一项艰巨的工作。
-
唯一“正确”的方法是正确工作的方法,这是底线。是否是虚函数;或者,重新定义一些相关的类,以便测试类认为它使用的是真实的类,而是使用返回模拟数据的类;或出于测试目的故意和受控违反单一定义规则;或预处理器技巧——一切都是公平的游戏。什么都能完成工作。我已经使用了所有这些方法,然后在不同的时间使用了一些。
-
你可以使用
#define MOCK_VIRTUAL final。然后当嘲笑它是非最终的;当不嘲笑时,它是最终的,因此被虚拟化。保留 RTTI,以减少不同行为的机会。
标签: c++ unit-testing