链接器错误 - 链接两个“应用程序”类型的项目以使用 Google 测试

Tha*_*lia 5 c++ linker-errors googletest

我正在尝试使用 Google Test 测试一个功能。

似乎一切都设置正确,并且它在没有 gtest 的情况下构建和执行得很好......(代码有点复杂,所以我无法在这里列出所有源文件,但不添加 gtest,文件正在链接正确,并按应有的方式运行)。

它是一个应用程序类型的项目。它有许多库依赖项……无关紧要。

测试项目作为单独的项目添加到解决方案中。它具有经过测试的项目作为依赖项。测试项目的.h文件只指向gtest....cpp(不是main,是标准的InitGoogleTest main)加上自己的头文件,被测项目的头文件,有如下图所示的测试.

有一个 TestedProject.lib 在项目构建时自动创建,即使它是一个应用程序。我已将 TestedProject.lib 作为库依赖项添加到 TestProject(在链接中)。

Class x
{
public:
  x(){}    // I didn't really need this, I only added the class so I have access to 
  ~x(){};  // non-class methods with gtest - but it still doesn't work
  bool myFunction(std::string a, double b, bool c);  
};
Run Code Online (Sandbox Code Playgroud)

执行:

bool x::myFunction(std::string a, double b, bool c)
{
  // implementation
  return false;
}

somewhere_else
{
  x x_instance;
  y = x_instance.myFunction("a", 1, false);   // works, all builds, executes, life is great
}
Run Code Online (Sandbox Code Playgroud)

添加单元测试:

class TheTest : public ::testing::Test
{
protected:
    x x_instance;
};

TEST_F(TheTest, Fail)
{
    EXPECT_FALSE(x_instance.myFunction("a", 1, false));     
}
Run Code Online (Sandbox Code Playgroud)

不建。链接错误(修改,如上面的示例代码,名称简化,希望我没有把内容搞乱)

Error   2   error LNK2019: unresolved external symbol 
"public: bool __thiscall x::myFunction(class std::basic_string<char,struct std::char_traits<char>,double,bool)" 
(?myFunction@x@@QAE_NV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@00000NNNN_N1@Z) 
referenced in function "private: virtual void __thiscall TheTest_Fail_Test::TestBody(void)" 
(?TestBody@TheTest_Fail_Test@@EAEXXZ)   C:\path\file.obj
Run Code Online (Sandbox Code Playgroud)

我以前做过这个 - 解决了链接错误 - 用谷歌测试写了几个测试 - 但我看不到任何遗漏。

作为测试,我写了一点

int test(){return 4;} 在头文件中,在类声明中...

然后,用 EXPECT_EQ(x.test(), 4) 替换测试;

有效。伟大的。但这意味着将所有经过测试的代码都放在一个文件、cpp 或其他文件中……这简直是不合理的。此应用程序项目中有几个文件。

我该如何解决这个问题?如何使用带有标题和实现文件的类进行 Google Test 链接和测试?当该标题/实现位于“应用程序”类型的不同项目中时?

到目前为止,我发现的唯一类似问题:Visual Studio 2008 上的 C++ linking issue when crosslinking different projects on the same solution

请帮我找到解决办法。

tou*_*ssa 8

还有另一种解决方案,我更喜欢它,因为这意味着您可以避免更改主项目:

向主项目添加“构建后操作”,以便为完全相同的源文件创建静态库。然后您可以简单地将此依赖项添加到您的 gtest 项目中。

每次编译主项目时,它都会构建应用程序和静态库。

这样您就不必创建第三个项目并保持配置同步。

希望能帮助到你。

  • 具体设置应该是:打开主项目属性,选择Build Event-&gt;Post-Build Event选项卡。使用命令 *lib /NOLOGO /OUT:"$(TargetPath).lib" "$(ProjectDir)\$(Configuration)\*.obj"* 这样就会生成一个 $(ProjectName).exe.lib 文件.exe 文件,它有利于静态链接到单元测试项目。 (5认同)
  • 3/3 在两个平台上始终构建 .lib 文件的正确命令是:`lib /NOLOGO /OUT:"$(TargetPath).lib" "$(ProjectDir)$(IntDir)*.obj"`。使用“$(IntDir)”。 (2认同)

Tha*_*lia 2

所以我会有一个答案:

我的问题有两个解决方案:

1)将应用程序项目分解为2个项目,其中一个将成为一个库,包含大部分代码;另一个是一个应用程序,包含一个微小的 main() ,它调用实际代码的入口点(例如参数解析方法或其他东西)。

然后,我可以添加一个单元测试项目 - 来测试该库。

2)不要分解项目。添加gtest项目,不要创建任何依赖项。将要测试的文件添加到 gtest 项目中。gtest 项目将是一个单独的可执行文件......包含它所需要的一切。(优点:测试时无依赖)

我更喜欢第一个版本。