![](/img/trans.png)
[英]How do you mock and test the same function in C/C++ with FFF and Google Test?
[英]How to do mock test via linker in C++
有时,我们需要进行模拟测试。 进行依赖注入最广泛使用的方法是使用模板或接口。
然而,有时,对于一些遗留代码,存在一些没有虚函数和模板的具体类。 由于某种原因我们不想或不能修改生产代码。 但是我们还是想对具体的类进行模拟测试。
已经有很多关于这个话题的讨论。 大多数人说,即使不是不可能,也很难做到这一点。
幸运的是,我似乎已经找到了曙光。
(1) Pavel Minaev 在Interfaces vs Templates for dependency injection in C++ 中的回答
使用 C++,还有另一种选择 - 您为模拟类提供与真实类完全相同的名称,并且在链接单元测试时,只需将它们与模拟对象/库文件而不是真实文件链接起来。
(2) sdg's answer in fake/mock nonvirtual C++ methods
我们有时使用的一种方法是将原始 .cpp 文件至少分成两部分。
然后测试设备可以提供它自己的实现; 有效地使用链接器为我们做脏活。
这在某些圈子中称为“链接接缝”。
理论上是的。 我们可以用一个简单的案例作为例子来演示它。
一个简单的程序存在两个类, A
和B
。 B 是 A 的用户。
当我们想做B类的单元测试时,我们可以在MockA.cpp
定义另一个A
并通过以下命令生成单元测试执行文件。
g++ testB.cpp B.cpp MockA.cpp
到了发布的时候,我们可以通过follow命令生成可执行文件
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
, MockB2
?
再者,如果B4
、 B5
、 B6
都需要做B3
,就显得很复杂了。
手动操作很复杂,很容易出错,也很难维护。
我不知道如何让链接器为我们做这些脏活?
上面链接中有人说该技术已经用于实践项目。 但我搜索了很多,并没有线索。
任何指向已经使用此技术的开源项目的链接都将非常有帮助。 使用 CMake 或 Makefile 进行编译对我来说更容易理解。
谢谢你的时间。
编辑
Mike van Dyke 分享了另一种没有虚函数的模拟方法。 该方法可以在不使用链接器的情况下进行模拟工作。 这是制作模拟的另一种解决方案。
我理解您的情况如下:为了测试B3
您需要真正的B3
和A1
、 A2
、 B1
和B2
。 您的假设是,您将使用与生产代码类似的库设置:将有一个带有B3
、 B4
、 B5
的库,但肯定不会带有B1
和B2
,因为这些将被模拟。
我的建议是,对于单元测试可执行文件,选择不同的库设置:创建单独的库libMockA1
、 libMockA2
等,并为libMockA2
的Bx
类创建类似的单独库。 然后,您可以在构建测试可执行文件时更独立地组合它们。 为了测试B3
您可以将B3
目标文件与libMockA1
、 libMockA2
、 libMockB1
和libMockB2
。 为了测试B4
您可以将B4
目标文件与例如libMockA1
、 libMockB1
和libMockB3
等libMockB1
libMockB3
。
或者,您可以完全放弃使用库进行单元测试,而仅单独链接目标文件。
您仍然需要为Ax
和Bx
类创建Bx
,但您可以为每个测试可执行文件单独组合它们 - 无需为每个测试可执行文件创建不同配置的库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.