如何在C++中通过链接器进行模拟测试
How to do mock test via linker in C++
有时,我们需要做模拟测试。进行依赖注入的最广泛使用的方法是使用模板或接口。
但是,有时,对于某些遗留代码,存在一些没有虚函数和模板的具体类。出于某种原因,我们不想或不能修改生产代码。但我们仍然想在具体类上进行模拟测试。
关于这个话题已经有很多讨论。大多数人说,如果不是不可能的话,很难做到这一点。
幸运的是,我似乎找到了黎明。
(1( Pavel Minaev在C++中用于依赖注入的接口与模板中的回答
使用 C++,还有另一种选择 - 你给你的模拟类指定与真实类完全相同的名称,并且在链接单元测试时,只需将它们与模拟对象/库文件而不是真实文件链接即可。
(2(SDG在假/模拟非虚拟C++方法中的答案
我们有时使用的一种方法是将原始.cpp文件拆分为至少两部分。
然后测试设备可以提供自己的实现;有效地使用链接器为我们完成繁琐的工作。
这在某些圈子里被称为"链接缝"。
理论上是的。我们可以用一个简单的案例作为例子来演示它。
一个简单的程序存在两个类,A
和B
。B 是 A 的用户。
当我们想做B类的单元测试时。我们可以在MockA.cpp
中定义另一个A
.并通过以下命令生成单元测试执行文件。
g++ testB.cpp B.cpp MockA.cpp
到了发布的时候,我们可以通过以下命令生成可执行文件
g++ Main.cpp B.cpp A.cpp
我的问题是我们如何在一个庞大的程序中实现它?
这是一个真正的程序,可能存在很多类,它们被打包到库中。
例如:一个庞大的程序需要使用两个库。libA
来自A1,A2,A3,...A100
级。libB
来自B1,B2,B3,....B100
班。
假设我们要对 B3 进行单元测试,并且我们希望A1
、A2
、B1
、B2
被嘲笑。我们怎么能做到这一点?
我们需要一个libA without A1,A2
、libB without B1,B2
、MockA1
、MockA2
、MockB1
、MockB2
?
而且,如果B4
、B5
、B6
都需要做类似B3
的事情,这似乎非常复杂。
手动操作很复杂,很容易出错,也很难维护。
我不知道如何让链接器为我们做肮脏的工作?
上面链接中的某人表示,该技术已经用于实践项目。但是我搜索了很多,却一无所知。
任何已经使用这种技术的开源项目的链接都将非常有帮助。使用CMake或Makefile进行编译对我来说会更好地理解。
谢谢你的时间。
编辑
Mike van Dyke分享了另一种在没有虚拟功能的情况下进行模拟的方法。 该方法可以制作模拟作品,而无需使用链接器。这是另一种进行模拟的解决方案。
将 googlemock 与非虚拟函数的假 impls 一起使用
我理解您的情况如下:为了测试B3
,您需要A1
,A2
,B1
和B2
的真实B3
和模拟。 你的假设是,你将使用与生产代码类似的库设置:会有一个库,有B3
、B4
、B5
,但肯定不是B1
和B2
,因为这些会被嘲笑。
我的建议是,对于单元测试可执行文件,选择不同的库设置:创建单独的库libMockA1
,libMockA2
等,以及类似的单个库,用于模拟的Bx
类。 然后,您可以在构建测试可执行文件时更独立地组合它们。 为了测试B3
,您可以将B3
对象文件与libMockA1
、libMockA2
、libMockB1
和libMockB2
链接。 为了测试B4
,您可以将B4
对象文件与例如libMockA1
、libMockB1
和libMockB3
等链接。
或者,您可以放弃使用库进行单元测试,而只单独链接对象文件。
您仍然需要为Ax
和Bx
类创建模拟,但随后您可以为每个测试可执行文件单独组合它们 - 而无需为每个测试可执行文件创建不同配置的库。
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- gmock / google-mock发出警告,并且通过模拟异常未通过测试
- 模拟测试中类的依赖关系
- 在类 gtest/gmock 进行单元测试时模拟成员函数C++
- 如何在C++中通过链接器进行模拟测试
- 如何在生产中避免vtable查找,并且仍然能够在单元测试中进行广泛的模拟
- 在谷歌测试中创建模拟类的向量
- C++ 谷歌模拟/单元测试:模拟方法未调用,原始方法是
- googlemock-如何模拟被测试类所拥有的对象
- 谷歌模拟如何在测试中使用模拟
- 在为函数编写单元测试时,我应该模拟所做的内部函数调用吗?
- EXPECT_CALL在谷歌测试中没有模拟
- 为什么谷歌测试/模拟显示 std::unique_ptr 泄露的模拟对象错误?
- 谷歌模拟:测试对象的某个属性
- 使用谷歌模拟测试C++时无法推断模板参数
- 模拟测试的const值
- 除了模拟测试之外,还无需额外使用接口
- 如何用谷歌测试模拟测试中的类中的方法
- 谷歌模拟测试一个类的真实行为
- 使用模拟测试迭代代码——它有意义吗?