需要一种在 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();
我是 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();