CppUTest 单元测试框架多重定义异常
CppUTest Unit Testing Framework Multiple Definition Exception
我将尝试将此作为一个纯粹的最小示例,以尽可能适用于更多人,并保护可能违反 NDA 的任何类型的代码共享。希望一切顺利!
我正在使用 CppUTest 和 CppUMock(使用 gcc/g++ 编译并使用 CMake 创建 makefile)与 Gitlab 持续集成软件一起为未来的软件提交和发布创建单元测试环境。但是,我 运行 遇到了一点问题。假设我有以下文件夹设置(除了 /tests 文件夹的内容,我几乎无法更改):
+-- src
+-- driver1.c
+-- driver2.c
+-- inc
+-- driver1.h
+-- driver2.h
+-- tests
+-- test_driver1.cpp
+-- test_driver2.cpp
+-- main.cpp
+-- cmakelists.txt
CMakeLists 文件将包含 inc 文件夹、src 文件夹的编译和 tests 文件夹的编译。但是,假设 driver2.c 依赖于 driver1.c 定义的方法。如果没有模拟设置,这很好,因为您可以正常测试对 driver2 方法的调用结果。但是,假设我想模拟 driver1 的 method1 函数,以便我可以检查 driver2 是否正确调用 method1(使用 CppUMock)。这通常没问题,如果 driver1 没有被编译,而是在 test_driver2.cpp 文件中添加类似这样的内容:
void method1(int n) {
mock().actualCall("method1").withParameter("n", n);
}
将导致与 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
应评论者的要求,包含结构如下:
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 在 driver1.h 中声明并在 driver1.c 中定义。我无法编辑这些文件。
我很乐意根据要求添加详细信息。
解决这个模拟问题的最佳方法是什么?
如果您想从 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)
完成模拟后,将 mock_driver1.cpp
依赖项替换为 driver1.cpp
。
这一切都假设您对每个测试驱动程序都有一个单独的可执行文件。
但是,如果你想拥有一个所有驱动程序都链接在一起的大型主程序,那么你就不能让真实的 method1
和模拟的 method1
共存。为此,我建议将模拟的 method1
包装在命名空间 mock
或类似的东西中,并且只在 test_driver2.cpp.
中调用 mock::test1
我将尝试将此作为一个纯粹的最小示例,以尽可能适用于更多人,并保护可能违反 NDA 的任何类型的代码共享。希望一切顺利!
我正在使用 CppUTest 和 CppUMock(使用 gcc/g++ 编译并使用 CMake 创建 makefile)与 Gitlab 持续集成软件一起为未来的软件提交和发布创建单元测试环境。但是,我 运行 遇到了一点问题。假设我有以下文件夹设置(除了 /tests 文件夹的内容,我几乎无法更改):
+-- src
+-- driver1.c
+-- driver2.c
+-- inc
+-- driver1.h
+-- driver2.h
+-- tests
+-- test_driver1.cpp
+-- test_driver2.cpp
+-- main.cpp
+-- cmakelists.txt
CMakeLists 文件将包含 inc 文件夹、src 文件夹的编译和 tests 文件夹的编译。但是,假设 driver2.c 依赖于 driver1.c 定义的方法。如果没有模拟设置,这很好,因为您可以正常测试对 driver2 方法的调用结果。但是,假设我想模拟 driver1 的 method1 函数,以便我可以检查 driver2 是否正确调用 method1(使用 CppUMock)。这通常没问题,如果 driver1 没有被编译,而是在 test_driver2.cpp 文件中添加类似这样的内容:
void method1(int n) {
mock().actualCall("method1").withParameter("n", n);
}
将导致与 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
应评论者的要求,包含结构如下:
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 在 driver1.h 中声明并在 driver1.c 中定义。我无法编辑这些文件。
我很乐意根据要求添加详细信息。
解决这个模拟问题的最佳方法是什么?
如果您想从 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)
完成模拟后,将 mock_driver1.cpp
依赖项替换为 driver1.cpp
。
这一切都假设您对每个测试驱动程序都有一个单独的可执行文件。
但是,如果你想拥有一个所有驱动程序都链接在一起的大型主程序,那么你就不能让真实的 method1
和模拟的 method1
共存。为此,我建议将模拟的 method1
包装在命名空间 mock
或类似的东西中,并且只在 test_driver2.cpp.
mock::test1