需要一种在 Google 测试中测试工厂 Class 的好方法

Need a good approach to test a Factory Class in Google Test

我是 google 测试的新手,总体上对 C++ 比较陌生。查看下面的简化示例,测试 CDeviceCreator 的通用方法是什么?我一定需要模拟吗?我读过 google 测试中的模拟,但很难理解它。您能否提供一个针对此案例的示例。提前致谢。

这是工厂的接口class

class IDeviceCreator
{
public:
    IDeviceCreator(){
    };
    virtual ~IDeviceCreator(){
    };
    virtual IDevice * CreateAnalogDevice() = 0 ;
    virtual IDevice * CreateDigitalDevice() = 0 ;
};

鉴于:CAnalogDevice 和 CDigitalDevice 正在实现 IDevice

这里是混凝土厂class

class CDeviceCreator : public IDeviceCreator
{
public:
    IDeviceCreator(){
    }
    virtual ~IDeviceCreator(){
    }
    virtual IDevice * CreateAnalogDevice(){
        IDevice * anlogDev;
        anlogDev = new CAnalogDevice();
        return anlogDev;
    }
    virtual IDevice * CreateDigitalDevice(){
        IDevice * digDev;
        digDev = new CDigitalDevice();
        return digDev;
    }
};

您的方法 CDeviceCreator::CreateAnalogDevice 调用构造函数 CAnalogDevice。最有可能的是,真正的构造函数实际上不应该在单元测试期间被调用:它的使用可能会导致 'annoyances',例如 a) 引入硬件依赖性,从而无法 运行 单元测试开发环境而不是目标系统,b)如果相应的代码很大,或者再次链接很多其他代码,则增加构建时间,c)可能库尚未完成或处于错误状态,d)......

出于这个原因,您希望将您的代码与这个真正的构造函数隔离开来,并改用替代品。您有几种实现隔离的可能性:

  • 在单元测试中使用(肮脏的)预处理器技巧,如 #defining CAnalogDevice 到其他东西。
  • 链接到您的 CAnalogDevice 测试特定实现。这个实现可能是一个模拟,但在这个简单的例子中,更简单的东西(比如存根)很可能也可以。

总结:您不一定非要使用模拟,但很可能您必须做一些事情来实现隔离。而且,当然这一切都适用于 CDigitalDevice。

还有一些您可能会觉得有价值的其他建议:

  • 你应该养成在定义时初始化值的习惯。也就是说,而不是写

    IDevice * digDev;
    digDev = new CDigitalDevice();
    

    更喜欢

    IDevice * digDev = new CDigitalDevice();
    
  • 有些人(包括我自己)喜欢随处使用 const。例如,如上所示更改初始化后:

    IDevice * const digDev = new CDigitalDevice();