Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linker error while unit testing with Visual Studio C++

I want to unit test my C++ project with Visual Studio. After adding the folders from my project as include path to my test project, I get linker errors when trying to compile the tests:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2019 unresolved external symbol "public: __thiscall Piece::Piece(enum Color)" (??0Piece@@QAE@W4Color@@@Z) referenced in function "public: __thiscall Bishop::Bishop(enum Color)" (??0Bishop@@QAE@W4Color@@@Z)    ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1   
Error   LNK2019 unresolved external symbol "public: __thiscall Board::~Board(void)" (??1Board@@QAE@XZ) referenced in function "public: void __thiscall ChessPlusPlusTests::BishopTests::ValidMovesTest(void)" (?ValidMovesTest@BishopTests@ChessPlusPlusTests@@QAEXXZ)  ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1   
Error   LNK2019 unresolved external symbol "public: void __thiscall Board::placePieceAt(class Piece * const,struct Position)" (?placePieceAt@Board@@QAEXQAVPiece@@UPosition@@@Z) referenced in function "public: void __thiscall ChessPlusPlusTests::BishopTests::ValidMovesTest(void)" (?ValidMovesTest@BishopTests@ChessPlusPlusTests@@QAEXXZ)    ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1   
Error   LNK2001 unresolved external symbol "public: virtual class std::vector<struct Position,class std::allocator<struct Position> > __thiscall Bishop::getMovesFor(struct Position,class Board &)" (?getMovesFor@Bishop@@UAE?AV?$vector@UPosition@@V?$allocator@UPosition@@@std@@@std@@UPosition@@AAVBoard@@@Z)   ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1   
Error   LNK2001 unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Bishop::toString(void)" (?toString@Bishop@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)    ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1   
Error   LNK2001 unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Bishop::toShortString(void)" (?toShortString@Bishop@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)  ChessPlusPlus-Tests D:\Documents\Projects\ChessPlusPlus\ChessPlusPlus-Tests\BishopTests.obj 1   

My test source code:

#include "stdafx.h"
#include "CppUnitTest.h"
#include "Bishop.h"
#include "Board.h"
#include "TestUtils.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace ChessPlusPlusTests
{
    TEST_CLASS(BishopTests)
    {
    public:

        TEST_METHOD(ValidMovesTest)
        {
            // Arrange
            Board board{};
            Bishop *piece = new Bishop{ Color::WHITE };
            Position pos{ 3,3 };
            board.placePieceAt(piece, pos);

            // Act
            auto validPositions = piece->getMovesFor(pos, board);

            // Assert
            TestUtils::AssertPositions(validPositions, {
                0,0,0,0,0,0,0,1,
                1,0,0,0,0,0,1,0,
                0,1,0,0,0,1,0,0,
                0,0,1,0,1,0,0,0,
                0,0,0,0,0,0,0,0,
                0,0,1,0,1,0,0,0,
                0,1,0,0,0,1,0,0,
                1,0,0,0,0,0,1,0,
            });
        }

    };
}

Without adding the include path's the test project doesn't compile, since the header file includes in the main project rely on the include paths.

The main project compiles just fine.

Can someone help me to understand whats going wrong?

Thanks!

like image 997
David Speck Avatar asked Dec 08 '17 21:12

David Speck


People also ask

How do I test a DLL in Visual Studio?

Run the testsOn the Test menu, choose Windows > Test Explorer. If not all of your tests are visible in the window, build the test project: right-click its node in Solution Explorer and choose Build or Rebuild. In Test Explorer, choose Run All, or select the specific tests you want to run.

How do I run a single unit test in Visual Studio?

Run tests in Test Explorer If Test Explorer is not visible, choose Test on the Visual Studio menu, choose Windows, and then choose Test Explorer (or press Ctrl + E, T). As you run, write, and rerun your tests, the Test Explorer displays the results in a default grouping of Project, Namespace, and Class.


2 Answers

I believe the chosen answer is not correct. Tests typically should be run in their environment; therefore, they should not access the implementation (.cpp)


When you create a separate Test Project on Visual Studio (VS 2017) you need to create a reference to the project you want to test (right-click test project -> Add -> Reference -> tick projects): Add a reference

If you see some linker errors, right-click from the Unit test project: Project->Linker->Input->Additional Dependencies->Edit then add the path to your .obj files. You could try something like "$(SolutionDir)ConsoleApplication1\$(IntDir)*.obj" where ConsoleApplication1 is the target project name.

Path to .obj

Initially, I only wanted to put a comment on Cornelis' post, but I couldn't.

like image 52
Patrice Thimothee Avatar answered Nov 15 '22 03:11

Patrice Thimothee


https://www.codeproject.com/Tips/1085171/How-To-Do-Unit-Testing-with-Cplusplus-in-Visual-St

I found there that you have to add your .h and .cpp files as existing files also to the test project. That is left out on the official documentation or I missed it.

Now it works!

like image 21
David Speck Avatar answered Nov 15 '22 04:11

David Speck