简体   繁体   English

CppUTest单元测试框架多重定义异常

[英]CppUTest Unit Testing Framework Multiple Definition Exception

I will try to make this a purely minimal example to be as applicable to as many people as possible as well as protect any sort of code sharing that might violate an NDA. 我将尝试将此作为一个纯粹的最小示例,以尽可能适用于尽可能多的人,并保护可能违反NDA的任何类型的代码共享。 Hope this is okay! 希望这没关系!

I am using CppUTest and CppUMock (compiling with gcc/g++ and makefiles created with CMake) in conjunction with Gitlab Continuous Integration software to create a unit testing environment for future commits and release of software. 我正在使用CppUTest和CppUMock(使用CMake编译gcc / g ++和makefile)与Gitlab Continuous Integration软件一起为未来的提交和软件发布创建单元测试环境。 However, I have run into a bit of a problem. 但是,我遇到了一些问题。 Let's say I have the following folder setup (that I have minimal ability to change, other than the contents of the /tests folder): 假设我有以下文件夹设置(除了/ tests文件夹的内容之外,我具有最小的更改能力):

+-- src
    +-- driver1.c
    +-- driver2.c
+-- inc
    +-- driver1.h
    +-- driver2.h
+-- tests
    +-- test_driver1.cpp
    +-- test_driver2.cpp
    +-- main.cpp
    +-- cmakelists.txt

The CMakeLists file will contain including of the inc folder, compilation of the src folder, and compilation of the tests folder. CMakeLists文件将包含inc文件夹的包含,src文件夹的编译以及tests文件夹的编译。 However, let's say that driver2.c relies on methods defined by driver1.c. 但是,假设driver2.c依赖于driver1.c定义的方法。 This is fine if there is no mocking setup because you can just test the results of calls to driver2's methods normally. 如果没有模拟设置,这很好,因为你可以正常测试对driver2方法的调用结果。 However, say that I want to mock driver1's method1 function so that I can check that driver2 calls method1 correctly (using CppUMock). 但是,假设我想模拟driver1的method1函数,以便我可以检查driver2是否正确调用了method1(使用CppUMock)。 This would usually be fine, if driver1 wasn't being compiled, but adding something like so to the test_driver2.cpp file: 如果没有编译driver1,那么通常会没问题,但是在test_driver2.cpp文件中添加类似的内容:

void method1(int n) {
    mock().actualCall("method1").withParameter("n", n);
}

Will cause a collision with the actual method1 in driver1.c with a linker error like so: 将导致与driver1.c中的实际method1发生冲突,并发生链接器错误,如下所示:

CMakeFiles/Tests.dir/.../src/driver1.c:(.text+0x11d): multiple definition of 'method1'
CMakeFiles/Tests.dir/.../src/test_driver2.cpp:(.text+0x0): first defined here

As per request of the commenter, here is what the include structure is like: 根据评论者的要求,包含结构如下:

driver1.c includes driver1.h (obviously)
driver2.c includes driver2.h (obviously)
driver2.h includes driver1.h (for calling method1)
test cpp files include their respective .h files
(test_driver1.cpp -> driver1.h and test_driver2.cpp -> driver2.h)

method1 is declared in driver1.h and defined in driver1.c. method1在driver1.h中声明并在driver1.c中定义。 I am not able to edit these files. 我无法编辑这些文件。

I'm happy to add details as requested. 我很乐意按要求添加详细信息。

What is the best way to get around this mocking issue? 解决这个嘲弄问题的最佳方法是什么?

If you want to mock method1 from driver1.h , just add the mocked definition in a separate mock_driver1.cpp and then in your CMakeLists.txt: 如果要从driver1.h模拟method1 ,只需将模拟的定义添加到单独的mock_driver1.cpp中,然后添加到CMakeLists.txt中:

add_executable(target1 test_driver1.cpp driver1.cpp)
add_executable(target2 test_driver2.cpp driver2.cpp mock_driver1.cpp)

Once you are done mocking, replace the mock_driver1.cpp dependency with driver1.cpp . 完成mock_driver1.cpp ,将mock_driver1.cpp依赖项替换为driver1.cpp

This all assumes you have a separate executable for each test driver. 这都假设您为每个测试驱动程序都有一个单独的可执行文件

However, if you want to have one big main program where all drivers are linked together, then you cannot have both the real method1 and the mocked method1 co-exist together. 但是,如果你想拥有所有驱动程序连接在一起的一个大主要项目,那么你就不能同时拥有真正的method1和嘲笑method1并存在一起。 For that, I'd recommend wrapping the mocked method1 in a namespace mock or something like that, and only call mock::test1 in test_driver2.cpp. 为此,我建议将mock method1包装在名称空间mock或类似的东西中,并且只在test_driver2.cpp中调用mock::test1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM