使用Google Mock来模拟在客户端代码中复制的对象
Using Google Mock to mock objects copied in client code
在这种情况下,我如何模拟依赖关系?
我有一个需要测试的客户端功能。它获取第三方API资源并调用该资源上的方法,用输出填充其其余参数:
void ClassA::enumerateConnectedDevices(ThirdPartyAPI::BusManager & busMgr, QList<QByteArray> &devices, QStringList &descriptions)
在这个函数流的某个时刻,它调用busMgr对象,该对象的签名如下:
ThirdPartyAPI::Error busMgr.GetNumOfCameras(...)
使用该调用的客户端代码如下所示:
ThirdPartyAPI::Error err = busMgr.GetNumOfCameras(&numCameras);
if (err != ThirdPartyAPI::ERROR_OK) { // compares against some enum
cout << "Error: " << err.GetDescription();
}
我遇到的问题是从GetNumberOfCameras返回到err局部变量的错误副本。在复制之前,模拟BusManager和Error类一直有效。由于mock error是ThirdPartyAPI::error的子类,因此赋值运算符将mock切片。第三方API构造有效的错误对象并返回它们。客户端代码只能复制构造或分配它们。
我所需要的只是从模拟的BusManager返回有效的模拟错误对象,以便SUT方法是可测试的。只要意图保持不变,我对重构SUT方法持开放态度。
我该怎么解决这个问题?
这听起来像是在处理C++中的一个经典问题:处理多态性时的切片问题。因为C++在运行时不知道您的子类,所以当您将模拟的Error对象分配给Error引用时,只有基类部分被复制("切片")。
一种解决方法是使用指针或智能指针而不是引用。这样就保留了多态性;"整体";对象,而不仅仅是基类部分。
因此,如果可能的话,您可以修改客户端函数以使用指针,然后根据需要使用多态性。
下面是一个看起来像什么的例子:
void ClassA::enumerateConnectedDevices(ThirdPartyAPI::BusManager* busMgr, QList<QByteArray> &devices, QStringList &descriptions)
{
int numCameras = 0;
ThirdPartyAPI::Error* err = busMgr->GetNumOfCameras(&numCameras);
if (*err != ThirdPartyAPI::ERROR_OK) { // compares against some enum
cout << "Error: " << err->GetDescription();
}
// Don't forget to delete your pointers if not using smart pointers!
delete err;
}
这样,BusManager mock可以返回一个指向mock Error的指针,并且将分配完整的mock,而不仅仅是基类部分。
如果API不允许您使用指针,并且您不能修改API,这可能会更具挑战性。然后,您需要找到一种方法来改变测试方式,或者重构代码以使其更具可测试性。例如,您可以将API调用封装在允许使用指针的类的新层中,并测试该层。
如果这有帮助或您需要更多帮助,请告诉我!
- 以下示例中如何避免代码复制?C++/库达
- 如何使用从C++代码写入时复制 BTRFS?
- 如果 iostream 对象不可复制,为什么以下代码是合法的?
- 为什么我的代码在尝试复制字符数组时引发 C6386 错误?
- 是否可以避免在以下代码中复制/移动构造函数的需要?
- 为什么在我的代码中调用复制构造函数而不是移动构造函数?
- 为什么在使用转换构造函数编译代码时需要 const 复制构造函数?
- C++具有移动和复制构造函数的类中的代码重复
- 如何在不复制此代码的情况下将多个函数放入多个命名空间?
- 表示行为与复制代码块的函数参数?
- 避免使用 auto 关键字从字面上复制 const 和非 const 的代码?
- 为什么在下面的代码中调用复制构造函数两次
- 从教科书中一对一复制的代码绝对没有任何作用
- 复制赋值和复制构造函数(代码C++的差异)
- 是否可以动态翻译QT应用程序而无需复制代码
- 我无法使用 c++(代码块)中的 fstream 将文件内容复制到另一个。如何运行该文件?
- 循环设计:计数和后续代码复制
- C++将格式化的代码复制到单词(如视觉助手)
- 将代码复制到RAM-如何一次复制多个功能
- 是否有任何方法可以避免跨类的不同构造函数进行代码复制