Search code examples
c++visual-studio-2017googletestlnk2019googlemock

visual studio 2017 LNK2019: unresolved external symbol In GoogleTestGoogleMock Project


I am a noobie with C++. My first learning project uses GoogleTest and GoolgleMock, but, of course, I am new to those also. I installed googletestmock.v.141 v101 via NuGet. My main app, AstronomyCalculations, builds and runs without a problem. My test app, GMock, throws three LNK2019 errors when I try to build it.

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);
}

Solution

  • The linker seems unable to find the functions easter::easter(void), easter::~easter(void), and easter::get_easter_date(int)const

    You are obviously including easter.h (and have it in your search path, or the compiler would have complained) but are you actually compiling easter.cpp or a mock object of it? (As far as I can tell from your sourcecode you are not actually mocking the class either). The header file is enough to satisfy the compiler, but when the linker tries to put the application together and realizes it is missing the object file, it balks - throwing LNK2019.

    I can only strongly reccommend you look deeper into the documentation available for gtest & gmock.

    In addition, you may also reconsider your naming schemes - Class types usually begin with an uppercase (i.e. Easter, not easter) to better tell them from variable names (which begin with lowercase). Also don't call your variables a, b, c, d - const auto a and its ilk are horrible to read, debug, and you will curse yourself I you ever find yourself in the postion of having to revisit the code after some weeks. Even if this were only some practice project, please also practice using good coding standards & naming conventions, so you (automatically) use them on bigger projects.