接口vs C ++中依赖注入的模板

时间:2009-07-14 20:44:39

标签: c++ unit-testing mocking

为了能够对我的C ++代码进行单元测试,我通常会将测试类的构造函数传递给一个或多个对象,这些对象可以是“生产代码”或伪造/模拟对象(让我们调用这些注入对象)。我是通过

完成的
  1. 创建“生产代码”类和假/模拟类继承的接口。
  2. 使被测试的类成为一个模板类,它将注入对象的类型作为模板参数,注入对象的实例作为构造函数的参数。
  3. 一些随意的想法:

    • 在我们有概念(C ++ 0x)之前,只有文档和参数命名会暗示提供被测试类的内容(使用模板时)。
    • 并不总是可以为遗留代码创建接口
    • 基本上只创建接口以便能够执行依赖注入
    • 以同样的方式:模拟被测试的类只是为了启用依赖注入

    你有什么想法?这个问题还有其他解决方案吗?

4 个答案:

答案 0 :(得分:8)

使用C ++,还有另一种选择 - 你给你的模拟类与真实类完全相同的名称,并且在链接单元测试时,只需将它们与模拟对象/库文件而不是真实文件链接。

答案 1 :(得分:4)

我认为接口选项更好,但是不必为测试创建公共基类。您可以从生产类继承您的mock类并覆盖必要的方法。你必须使这些方法成为虚拟方法,但这就是像mockpp这样的工具的工作原理,它们也允许自动化这个过程。

答案 2 :(得分:3)

模板对运行时的性能损失会稍微减少(间接次数减少,调用次数减少,内联优化更多),但会使编译时受到很高的惩罚......

我认为为此目的,接口更好(直到我们在C ++ 0x TR1中有概念)...除非你不能减慢一些“瓶颈代码”。接口在运行时更具动态性和可切换性。

请记住,您可以使用默认注入对象(真实的)来构造您的类,但是您可以让工厂在您的测试中注入模拟对象......您甚至不需要子类化。

答案 3 :(得分:2)

不知道它是否有帮助,但你可以拥有模板构造函数:

struct Class_Under_Test
{
    template <typename Injected>
    Class_Under_Test()
    {
         ...

    // and even specialize them
    template <>
    Class_Under_Test <A_Specific_Injection_Class>
    {
        ...

只包括实际使用的那个。