C++ unitTest with LinkTime substitution - c++

I'm reading "Test-Driven Development for Embedded C," by James W. Grenning.
I'd like to reproduce case with "Link-Time Substitution" using Visual Studio Community 2019 and gTest.
I have the following code:
production_code staticly linked library
foo.cpp
#include "foo.h"
int foo(int x) {
return x + 1;
}
foo.h
#ifndef _foo_
#define _foo_
int foo(int x);
#endif //_foo_
In gtest project production_code library is included via reference
test.cpp
#include "gtest\gtest.h"
#include "gmock\gmock.h"
#include "..\prod\foo.h"
//fake implementation of production code foo
int foo(int x) {
return x - 1;
}
TEST(TestCaseName, TestName) {
auto x = foo(5);
EXPECT_EQ(x, 4);
}
The linker gives me following error:
1>prod.lib(foo.obj) : error LNK2005: "int __cdecl foo(int)"
(?foo##YAHH#Z) already defined in test.obj 1>C:\Example\prod_test.exe
: fatal error LNK1169: one or more multiply defined symbols found
What have I missed here? Why doesn't this work?
If I add the command "/FORCE:MULTIPLE" to linker, then I get only warning, but I think that this is not the right approach to doing this.

This situation occurs because you defined foo(int) in 2 places: foo.cpp and test.cpp and you build your code with this files. If you need to run some test with a stub (fake function foo(int) in this case) you need to create 2 targets of build for:
building of your real application
building of a special application for unit testing (and than run it)
And when you build the application for unit testing, you link it with test.cpp (but not with foo.cpp). Also when you build your real application you link it with foo.cpp (but not with test.cpp).
Note: it's make sense to test real code and create a stub when this stub provides some additional functionality according to idea of a test (for example, you check your sort() function but you can use stub to generate data for sort() because the data are provided after some complex algorithm finished working and the computing takes a lot of time) or you don't want to use some resources (for example, you check your sort() function but you use a network connection to a server to get real data for sort()) or you need to provide some specific data for testing you algorithm (for example, to check a corner case using specific data; or maybe you have found the sort() doesn't work with specific data). But again, it's make sense to test real code.

Related

Using static library in current project

I'm facing the error when I'm linking an external library and code with the current project. You will understand the problem by this example.
//foo.h
namespace LMS
{
class foo
{
foo(); //implementation in cpp
foo(int dummy) //implemented here
{
//something
}
};
} // namespace LMS
//foo.cpp
#include"foo.h"
namespace LMS
{
foo::foo()
{
//something
}
} // namespace LMS
//externalProgram.h
#include "foo.h"
LMS::foo *ptr;
ptr = new LMS::foo(); //Linking error: LNK 2019
ptr = new LMS::foo(2); //No error
Now the problem is that the external program doesn't know about the foo.cpp and the implementation of class foo methods in it. I'm currently using VS2019 and using two projects in the same solution. I've tried several ways to correct this but it didn't work out. The current way I'm seeing is to implement all the functions in header files.
EDIT: I've already linked the files!!
You should be able to mark your externalProgram project as dependent on the foo project. This will link foo.o in with external program.
Using the UI you will select this in
Project > Project Dependencies : Depends on ...
If that is correct, then the problem is more subtle, sometimes just a simple typo. At this point you want to use the command line tools to break apart the library and confirm the object files, and break apart the object files and confirm the symbols within. A ten year old SO posting discusses using lib.exe to example the library file. The dumpbin tool has a /symbols option that might also be handy for looking at the actual code generated.

How to access my code using Visual Studio CppUnitTestFramework

I wish to unit test my code. It is a proprietary step in a task I have, the code of which I already wrote.
I am using VS Community 2017 v.15.9.7. I have followed the instructions of this site to the utmost detail, line by line:
https://blogs.msdn.microsoft.com/vcblog/2017/04/19/cpp-testing-in-visual-studio/#Setup
But after all the includes I get two errors :
1) Error LNK1120 1 unresolved externals UnitTest1 \source\repos\Primes\Debug\UnitTest1.dll 1
2) Error LNK2019 unresolved external symbol "public: bool __thiscall SearchPrimes::IsPrime(int)" (?IsPrime#SearchPrimes##QAE_NH#Z) referenced in function "public: void __thiscall UnitTest1::TestClass::IsOdd(void)" (?IsOdd#TestClass#UnitTest1##QAEXXZ) UnitTest1 C:\Users\Velzevoul\source\repos\Primes\UnitTest1\unittest1.obj
I have tried moving files, but I thing randomly moving them around will do more harm than good. I read about including the "stdafx.h" to my "source", but that made thing worse, as more errors kept popping up.
Here are the header files of the code I wrote:
#pragma once
#include <vector>
#include "XMLParser.h"
class SearchPrimes
{
public:
std::vector<int> RangePrime(const std::pair<int, int>&);
//Setting the range to search for prime numbers, executing the algorithm
bool IsPrime(int); //The algorithm that checks if a number is prime
bool IsOdd(int); //Checking if a number if even or odd
};
#pragma once
#include <iostream>
#include <vector>
class XMLParser
{
public:
void removeTags(std::string&); //Removing the brackets of the tags of the .xml
std::string openFile(std::string); //Opening a file
std::vector<std::string> readFile(const std::string&, std::string);
//Getting the text from the .xml file to a vector
std::vector<std::pair<int, int> > stringsToInts();
//Finding the values of the tags that contain the ranges
//and converting the string numbers to a vector<int>
};
Here is the test.cpp
#include "stdafx.h"
#include "CppUnitTest.h"
#include "/Users/Velzevoul/source/repos/Primes/Primes/SearchPrimes.h"
#include "/Users/Velzevoul/source/repos/Primes/Primes/XMLParser.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest1
{
TEST_CLASS(TestClass)
{
public:
TEST_METHOD(IsOdd)
{
SearchPrimes prime;
Assert::IsTrue(prime.IsPrime(4));
}
};
}
What do I have to do in order to solve the external dependencies? The article says, that once I follow the steps I can begin. The test is in a separate project, as the article suggests. If you think that the problem may be related to my main() function, please tell me to include it. I do not right now, because it's quite lengthy.
I thank you for your time in advance!
That article is suggesting that you can just link to a Windows executable the same way you would a DLL. I suppose this is theoretically be possible if your executable has been set up to export its functions, but it seems like an odd thing to do.
There are two options for accessing the code under test in a C++ unit test project:
Add the source modules (.cpp/.h) to your unit test project.
Link with a library containing the code.
If your project is relatively simple, with just a few .cpp modules, then option 1 is probably the way to go. Right-click your unit test project, select "Add -> Existing Item..." and add the .cpp modules you want to test.
For a more complex project with many source modules, option 2 might be a better option. Create one or more library projects (static or dynamic) to contain your source modules, then link both the executable and unit test projects with the library.
A good practice is to create one unit test project for each project to be tested. Give the unit test project a name that indicates what project it is testing, i.e. MyExecutable and MyExecutable.Test, MyLibrary and MyLibrary.Test, etc.

Eclipse CDT Including Unreferenced Files in Automatically Generated Build

I'm new to cpp in eclipse and trying to mess with simple builds. I have made a basic project which automatically generates build info (no user-defined makefile).
Simple (Working) Case
I made a "Hello World" project called Test (not an empty project). It has one file - Test.cpp with a main() in => builds and runs fine.
Test.cpp
int main() {
// output some stuff
}
Slightly More Complex (Working) Case
I make a new file called Main.cpp. Move the main() function into Main.cpp and make a decleration of a function in main too - void test();
The test() function lives in Test.cpp, which is where I provide the function definition.
Main.cpp
#include <iostream>
void test();
int main() {
// Use test()
}
Test.cpp
#include <iostream>
void test() {
// output some stuff
}
Build it, there are now two .o files in the Debug directory - Test.o and Main.o. This runs fine.
The Problem
Now I try to introduce a third file - Limits.cpp.
Limits.cpp
#include <iostream>
void printLimits() {
// Print out limits for different integer sizes
}
Again I provide a deceleration of this function in Main.cpp.
Main.cpp
#include <iostream>
void test();
void printLimits();
int main() {
// Use printLimits()
}
This time there is no object file created for Limits in the Debug folder => the build fails.
Main.cpp:*line* undefined reference to `getLimits()'
It just looks like the autogenerated build config for the project is duff. I've tried looking around the project properties but I have had no luck. I've tried including the path/file in Include Paths/Include files, other objects, and I've checked just about every other property I can see. This has been frustrating me for two days.
The strange thing about this is case 2. It looks like because Test.cpp was the first file made it always includes this in the build? (even if it is not imported). Where as because Limits.cpp is new and not imported it doesn't generate an object file so it can't link the function.
I could me making an error by needing to include the files but my understanding is if all the object files make it to the linker then all will be well (ie I just need the function declarations when making the object files which is what I have here).
With a "Blank project" it seems to compile all the cpp files even if they are never used so my case above works. (Although, it doesn't work for files in subfolders of src). Looks like its a "feature" of the "Hello world" project type but it's going to drive me crazy knowing there must be a way to get it to do this.
If anyone knows if it is possible to include this file without writing my own makefile (I'm not a makefile guru (yet!)), or let me know if this is not possible with autogen CDT that would be great.
Using MinGW GCC toolchain.
Thanks

GMock doesn't compile - GTEST_EXCLUSIVE_LOCK_REQUIRED seems to not be defined

I'm trying to build a simple mocked class
#include "interpolation.hpp"
#include <gtest/gtest.h>
#include <gmock/gmock.h>
class MockInterp1D : public Interp1DBase {
public:
MOCK_METHOD1(evaluateAt, double(double));
MOCK_METHOD2(evaluateAt, double(double, int));
};
based on the following base class
class Interp1DBase {
public:
virtual double evaluateAt(double) const = 0;
virtual double evaluateAt(double, int) const = 0;
virtual ~Interp1DBase() { };
};
using Google Mocks. When I try to compile the tests where this mock is used, I get the following error:
In file included from /usr/include/gmock/gmock-generated-function-mockers.h:43:0,
from /usr/include/gmock/gmock.h:61,
from /home/tlycken/exjobb/Code/alpha-orbit-follower/test/interpolation/interpolation-mocks.hpp:4,
from /home/tlycken/exjobb/Code/alpha-orbit-follower/test/physics/B-field-tests.hpp:6,
from /home/tlycken/exjobb/Code/alpha-orbit-follower/test/physics/B-field-tests.cpp:2:
/usr/include/gmock/gmock-spec-builders.h:134:41: error: expected ‘;’ at end of member declaration
bool VerifyAndClearExpectationsLocked()
^
and then literally hundreds of similar syntax or definition errors all pointing to files within GMock.
I took a look at gmock-spec-builder.h:134, and found the following (in some context):
// Verifies that all expectations on this mock function have been
// satisfied. Reports one or more Google Test non-fatal failures
// and returns false if not.
bool VerifyAndClearExpectationsLocked()
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
which led me to believe that GTEST_EXCLUSIVE_LOCK_REQUIRED_ might be a macro that for some reason wasn't defined. And indeed, after digging through all header files included from either gmock/gmock.h or gtest/gtest.h I still haven't found the definition of that macro.
What am I doing wrong here?
UPDATE:
I've been able to produce an even simple minimal example:
// in file mock-test.cpp
#include <gmock/gmock.h>
// Yeah, that's the only content
Compile with
g++ -o mock-test.o -c mock-test.cpp
Causes the same error.
I've installed GMock through sudo apt-get install google-mock, which gave me a folder under /usr/src where I could run cmake . followed by make to generate library files which I copied to /usr/lib. The header files were already in /usr/include so I didn't do anything about them manually.
I got the same error when I tried to compile using gmock 1.7 with gtest 1.6. Make sure you are using the same version of gtest.
I don't know how to use g-mock in gcc.
But basically we use in windows like this.
Your class definitions are right.
Did you use those functions like
EXPECT_CALL(classobj, exact functionname as it looks in definition).AtLeast(Times(0)).Return(0);
then
classobj.exact functionname as it looks in definition()
Try this I think it should work. If you want it in detail, just let me know I will expand the same with some typical example.
There are the appropriate sources & headers in the /usr/src/gmock folder.
Your job is only overwrite the whole content of folders:
/usr/src/gmock/gtest/src -> /usr/src/gtest/src
/usr/src/gmock/gtest/cmake -> /usr/src/gtest/cmake
/usr/src/gmock/gtest/CMakeLists.txt-> /usr/src/gtest/CMakeLists.txt
/usr/src/gmock/gtest/include/gtest -> /usr/include/gtest/

Unit Tests fail with exception code c0000005

I am trying to create Unit Tests in Visual Studios 2012 using a Native Unit Test Project.
This is the test I have:
TEST_METHOD(CalculationsRoundTests)
{
int result = Calculations::Round(1.0);
Assert::AreEqual(1, result);
}
Exporting the Class:
#ifdef EXPORT_TEST_FUNCTIONS
#define MY_CALCULATIONS_EXPORT __declspec(dllexport)
#else
#define MY_CALCULATIONS_EXPORT
#endif
...
class CALCULATIONS_EXPORT Calculations {
...
public:
static int Round(const double& x);
The function itself:
int Calculations::Round(const double& x)
{
int temp;
if (floor(x) + 0.5 > x)
temp = floor(x);
else
temp = ceil(x);
return int(temp);
}
However, the test nearly always fails with error code c0000005 (Access Violation).
The test will fail the first time that x, or any other variable that may be declared in the function, is used.
I followed the instructions at Unresolved externals when compiling unit tests for Visual C++ 2012
This is a known bug. Unfortunately, Microsoft considers this as "Won't Fix".
In short, there are two workarounds:
Compile the actual project in release mode and the test project in debug mode.
Outsource all testable functions to a static library project.
I never figured out why the test would cause an access violation when it was run; however, I'm sure I had set something up wrong.
To remove this error, I changed the structure of my Visual Studio solution to have the majority of the code be in a static library (.lib) project which will contain the implementation of my program. By doing this, all of the classes and functions for my program in the project are automatically exported, so I don't need to use __declspec(dllexport).
Then, I created a small Win32 Console Application, which will create the .exe file for my program, that references the .lib project. The purpose of this project is to create the executable file for my program, so all it needed was a main that would call the start of my code in the .lib project.
After I did this, I was able to get the Native Unit Test project to work easily by just getting it to also reference the .lib project, and I haven't had any access errors since.