visual studio 2017 LNK2019:GoogleTestGoogleMock 项目中未解析的外部符号

visual studio 2017 LNK2019: unresolved external symbol In GoogleTestGoogleMock Project

我是 C++ 新手。我的第一个学习项目使用 GoogleTest 和 GoolgleMock,但是,当然,我也是新手。我通过 NuGet 安装了 googletestmock.v.141 v101。我的主要应用程序 AstronomyCalculations 可以毫无问题地构建和运行。我的测试应用程序 GMock 在尝试构建时抛出三个 LNK2019 错误。

Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol "public: __cdecl easter::easter(void)" (??0easter@@QEAA@XZ) referenced in function "private: virtual void __cdecl GET_THE_DATE_OF_EASTER_ShouldReturnDateOfEaster_Test::TestBody(void)" (?TestBody@GET_THE_DATE_OF_EASTER_ShouldReturnDateOfEaster_Test@@EEAAXXZ) GMock D:\Dev\Projects\AstronomyCalculations\GMock\GMock.obj 1

Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol "public: __cdecl easter::~easter(void)" (??1easter@@QEAA@XZ) referenced in function "private: virtual void __cdecl GET_THE_DATE_OF_EASTER_ShouldReturnDateOfEaster_Test::TestBody(void)" (?TestBody@GET_THE_DATE_OF_EASTER_ShouldReturnDateOfEaster_Test@@EEAAXXZ) GMock D:\Dev\Projects\AstronomyCalculations\GMock\GMock.obj 1

Severity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol "public: struct tm __cdecl easter::get_easter_date(int)const " (?get_easter_date@easter@@QEBA?AUtm@@H@Z) referenced in function "private: virtual void __cdecl GET_THE_DATE_OF_EASTER_ShouldReturnDateOfEaster_Test::TestBody(void)" (?TestBody@GET_THE_DATE_OF_EASTER_ShouldReturnDateOfEaster_Test@@EEAAXXZ) GMock D:\Dev\Projects\AstronomyCalculations\GMock\GMock.obj 1

// AstronomyCalculations.cpp
int main() {
return 0;
}

// Easter.h
#pragma once
#include <ctime>
#include <string>
class easter
{
public:
easter();
~easter();

tm get_easter_date(int easter_year) const;
};

// Easter.cpp
#include "Easter.h"

easter::easter()
{
}

easter::~easter()
= default;

tm easter::get_easter_date(const int easter_year) const
{
 const auto a = easter_year % 19;
 const auto b = easter_year / 100;
 const auto c = easter_year % 100;
 const auto d = b / 4;
 const auto e = b % 4;
 const auto f = (b + 8) / 25;
 const auto g = (b - f + 1) / 3;
 const auto h = ((19 * a) + b - d - g + 15) % 30;
 const auto i = c / 4;
 const auto k = c % 4;
 const auto l = (32 + (2 * e) + (2 * i) - h - k) % 7;
 const auto m = (a + (11 * h) + (22 * l)) / 451;
 const auto easter_month = (h + l - (7 * m) + 114) / 31;
 const auto easter_day = ((h + l - (7 * m) + 114) % 31) + 1;

 auto date_string = std::to_string(easter_year) +
    "-" + 
    std::to_string(easter_month) + 
    "-" +
    std::to_string(easter_day) +
    " 00:00:00";    

char date[20]; //a 1 char space for null is also required
strcpy_s(date, date_string.c_str());

tm ltm{};
char seps[] = " -:";
char *next_token = nullptr;

auto token = strtok_s(date, seps, &next_token);
ltm.tm_year = strtol(token, nullptr, 10);

token = strtok_s(nullptr, seps, &next_token);
ltm.tm_mon = strtol(token, nullptr, 10);

token = strtok_s(nullptr, seps, &next_token);
ltm.tm_mday = strtol(token, nullptr, 10);

token = strtok_s(nullptr, seps, &next_token);
ltm.tm_hour = strtol(token, nullptr, 10);

token = strtok_s(nullptr, seps, &next_token);
ltm.tm_min = strtol(token, nullptr, 10);

token = strtok_s(nullptr, seps, &next_token);
ltm.tm_sec = strtol(token, nullptr, 10);

ltm.tm_wday = 0;

return ltm;
}


// GMock.cpp
#include "stdafx.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "Easter.h"

int main(int argc, char** argv)
{
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}

TEST(GET_THE_DATE_OF_EASTER, ShouldReturnDateOfEaster)
{
easter estr;

const auto result = estr.get_easter_date(2000);

ASSERT_EQ(result.tm_year, 2000);
}

链接器似乎无法找到函数 easter::easter(void)easter::~easter(void)easter::get_easter_date(int)const

您显然包含了 easter.h(并将其包含在您的搜索路径中,否则编译器会抱怨)但您实际上是在编译 easter.cpp 还是它的模拟对象? (据我从您的源代码中可以看出,您实际上也没有在嘲笑 class )。头文件足以满足编译器的要求,但是当链接器试图将应用程序放在一起并意识到它缺少目标文件时,它会犹豫 - 抛出 LNK2019。

我只能强烈建议您深入研究 documentation available 的 gtest 和 gmock。

此外,您还可以重新考虑您的命名方案 - Class 类型通常以大写字母开头(即复活节,而不是复活节),以便更好地从变量名(以小写字母开头)中区分它们。也不要将你的变量称为 a、b、c、d - const auto a 及其类似的东西读起来、调试起来都很糟糕,你 诅咒你自己 我你会发现自己几周后不得不重新访问代码。即使这只是一些练习项目,也请练习使用良好的编码标准和命名约定,以便您(自动)在更大的项目中使用它们。

当我发现可以在 Visual Studio 2017 年将 GoogleTest 作为一个新项目添加时,我终于解决了这个问题。当然,我必须先删除我原来的测试项目,然后再添加新的测试项目。最后一切都解决了,但是,当然,我不知道为什么 link 错误会出现在我的原始测试项目中;除了 CharonX 的见解。