C++ 使用链接时间替换进行单元测试

C++ unitTest with LinkTime substitution

本文关键字:换进 单元测试 替换 时间 链接 C++      更新时间:2023-10-16

我正在阅读James W. Grenning的《嵌入式C的测试驱动开发》。

我想使用Visual Studio Community 2019和gTest重现"链接时间替换"的情况。

我有以下代码:

production_code静态链接库

傅.cpp

#include "foo.h"
int foo(int x) {
return x + 1;
}

福.H

#ifndef _foo_
#define _foo_
int foo(int x);
#endif //_foo_

在gtest项目中production_code库通过引用包含在内测试.cpp

#include "gtestgtest.h"
#include "gmockgmock.h"
#include "..prodfoo.h"
//fake implementation of production code foo
int foo(int x) {
return x - 1;
}
TEST(TestCaseName, TestName) {
auto x = foo(5);
EXPECT_EQ(x, 4);
}

链接器给我以下错误:

1>prod.lib(foo.obj(:错误LNK2005:"int __cdecl foo(int(" (?foo@@YAHH@Z( 已在 test.obj 1>C:\Example\prod_test.exe 中定义 :致命错误LNK1169:找到一个或多个乘法定义的符号

我在这里错过了什么?为什么这不起作用?

如果我将命令"/FORCE:MULTIPLE"添加到链接器,那么我只会得到警告,但我认为这不是这样做的正确方法。

出现这种情况是因为您在 2 个位置定义了foo(int)foo.cpptest.cpp并且使用此文件构建代码。如果您需要使用存根运行一些测试(在这种情况下foo(int)假函数(,则需要为其创建 2 个构建目标:

  1. 构建您的实际应用程序
  2. 为单元测试构建一个特殊的应用程序(然后运行它(

当您为单元测试构建应用程序时,您可以将其与test链接.cpp(但不与foo.cpp链接(。此外,当你构建你的实际应用程序时,你把它与foo.cpp(而不是test.cpp链接(。

注意:当此存根根据测试的想法提供一些附加功能时,测试真实代码并创建一个存根是有意义的(例如,您检查sort()函数,但您可以使用存根生成sort()数据,因为数据是在某些复杂算法完成工作并且计算需要大量时间后提供的(,或者您不想使用某些资源(例如, 您检查sort()函数,但您使用与服务器的网络连接来获取sort()(的真实数据,或者您需要提供一些特定数据来测试算法(例如,使用特定数据检查极端情况;或者您可能发现sort()不适用于特定数据(。但同样,测试真实代码是有意义的。