如何正确模拟单元测试的对象

时间:2016-12-05 19:34:34

标签: c++ unit-testing mocking

我发现单元测试是一件好事,但我在如何正确分离代码单元方面遇到了困难。这并不是很明显,但只要您的单元测试依赖于另一个“生产代码单元”,测试的可维护性及其优势就会迅速降低。这就是为什么我们有模拟或存根来实现“单位”与其他一切的分离。

这样做的方法当然是通过接口。但是我发现这种方法对接口的限制施加了相当严格的限制。例如,让我们考虑以下类:

class Val
{
public:
    void set(int value) { m_Val = value; }
    void get() const { return m_Val; } 
private:
    int m_Val = 0;
};

一切都很好,直到你有另一个使用Val的课程:

class SomeClass
{
public:
    void printValue(const Val &val) { std::cout << val.get(); }
};

现在,为了进行单元测试SomeClass,您应该模拟或存根Val。据我所知,在C ++中只有两种方法可以做到:

1)将Val的方法设为虚拟。然后,类ValMock可以从Val继承并重新实现方法以满足测试的需要。问题是您通常不希望为单元测试设计接口。我觉得这个相当具有侵略性,与成本(vtable查找等)相比,测试的好处相当令人难以置信。

2)进行Val的模拟实现。将编译的单独源文件(可能在另一个库中)并且测试将链接到该文件而不是原始文件。然而,这种方法也有成本,而且不是很小。首先,由于双重符号定义,您的标头中可能没有内联定义。第二,如果你测试的类的实现与你模拟的类的定义在同一个库中,你仍然会得到重复的符号。使用预处理器宏可以解决这个问题,但我发现它不是一个非常干净的解决方法。

可能还有第三种方式吗?或者我描述的首选方法是什么?测试的附加价值很高,但设计成本似乎比我第一次开始使用时看起来要高得多。

0 个答案:

没有答案