3
votes

I'm trying to learn how to use unit tests in Visual Studio with C++.

I made an uber simple class called Adder that, as you might guess, adds 2 numbers.

Here is the .h file for it:

#ifndef ADDER
#define ADDER

class Adder {

private:
    int num1, num2;

public:
    Adder(int, int);
    ~Adder();

    int add();

};

#endif

So I made a new project with Native Unit Test and made a reference in it to my Adder project. I couldn't include the .h file with just #include "adder.h" so I had to use a relative path. I read through Microsoft's Tutorial and it looks like you have to use this kind of path.

My problem is that I can't get the unit test to recognize the methods of my Adder class. Here's my unit test:

#include "stdafx.h"
#include "CppUnitTest.h"
#include "../addClass/adder.h" // Added a reference but still can't find without relative path

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{       
    TEST_CLASS(Adder)
    {
    public:

        TEST_METHOD(add) {

            Adder adder1(1, 1); // Won't recognize constructor

            int num = adder1.add(); // Won't recognize function

            Assert::AreEqual(2, num); 

        }

    };
}

I tried getting rid of the namespace UnitTest1 since it looked like Microsoft didn't have that in their tutorial. This didn't work though. I'm not sure how to get the Unit Test to recognize my method definitions.

Just in case I messed something up in the implementation file for the Adder class i'll put it here but I don't think that's the problem.

#include "adder.h"

Adder::Adder(int a=0, int b=1):num1(a), num2(b){}
Adder::~Adder(){}

int Adder::add() {

    return num1 + num2;

}

EDIT: Here are the errors i'm getting:

line 15 in unittest1.cpp: no instance of constructor "UnitTest1::Adder::Adder" matches the argument list

line 17 in unittest1.cpp: a value of type "void" cannot be used to initalize an entity of type "int"

line 15 in unittest1.cpp: 'UnitTest::Adder:: UnitTest1 Adder': no overloaded function takes 2 arguments

line 17 in unittest1.cpp: 'initializing': cannot convert from 'void' to 'int'

EDIT 2:

Okay so I changed the unit test file to this:

#include "stdafx.h"
#include "CppUnitTest.h"
#include "../addClass/adder.h" // Added a reference but still can't find without relative path

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest1
{       
    TEST_CLASS(test)
    {
    public:

        TEST_METHOD(add) {

            ::Adder adder1(1,1); // recognizes constructor

            int num = adder1.add(); // recognizes function

            Assert::AreEqual(1, num); 

        }

    };
}

However now I get Linker errors:

LNK2019 unresolved external symbol "public: __thiscall Adder::Adder(int,int)" (??0Adder@@QAE@HH@Z) referenced in function "public: void __thiscall UnitTest1::test::add(void)" (?add@test@UnitTest1@@QAEXXZ) UnitTest1 C:\Users\Matt\documents\visual studio 2015\Projects\addClass\UnitTest1\unittest1.obj

LNK2019 unresolved external symbol "public: __thiscall Adder::~Adder(void)" (??1Adder@@QAE@XZ) referenced in function "public: void __thiscall UnitTest1::test::add(void)" (?add@test@UnitTest1@@QAEXXZ) UnitTest1 C:\Users\Matt\documents\visual studio 2015\Projects\addClass\UnitTest1\unittest1.obj 1

LNK2019 unresolved external symbol "public: int __thiscall Adder::add(void)" (?add@Adder@@QAEHXZ) referenced in function "public: void __thiscall UnitTest1::test::add(void)" (?add@test@UnitTest1@@QAEXXZ) UnitTest1 C:\Users\Matt\documents\visual studio 2015\Projects\addClass\UnitTest1\unittest1.obj 1

2
What is the error do you get when trying to compile?Rama
have you considered changing the TEST_CLASS name or using ::Adder adder1(1, 1); in your test?luantkow
I changed the TEST_CLASS name and used the scope operator, which got rid of the errors I posted, but now I have a bunch of Linker errors which i'll post @user3188346Matt Corby
I think that you need to export your class definition. See second and third step in the tutorial from the link you have posted.luantkow

2 Answers

1
votes

I had a similar issue, but with an Application type project (as opposed to a DLL project).

For classes defined in the project under test which aren't exported, you have to tell the Linker of the tester-project where they are implemented.

Even after adding the project-under-test as a reference to the tester-project, I also had to modify the Linker options in the tester-project to include the object files which implement the classes under test.

See Writing Unit tests for C/C++ with the Microsoft Unit Testing Framework for C++ for details. Specifically the section titled "To link the tests to the object or library files".

I went from having the same Linker errors you did to having a working test environment. It'd be nice if by "Referencing" the project-under-test from the tester-project, it'd handle this sort of stuff for you.

0
votes

I ran into this problem as well. I found a couple things that worked, though I'm not sure either is the "correct" solution. One option is to include the .cpp file as well as the .h file in your unit test class. This is pretty ugly.

The second option that worked was right-clicking on the unit test project, selecting Add, and selecting Existing Item. Navigate to the .cpp file in the window explorer that appears and select Add. You can additionally create a new filter for storing these source files if you do not want them mixed in with your unit testing source files.