gtest, undefined reference to 'testing::Test::~Test()', testing::Test::Test() - c++

i installed the gtest using apt-get install libgtest-dev
and i am trying to check if that is working or not.
so i make simple code for testing in eclipse.
but there are error,
undefined reference to 'testing::Test::~Test()'
undefined reference
to 'testing::Test::Test()'
conversely if i change the inheritance at the ATest class as protected the error disappear but
the other error occur
testing::Test is inaccessible base of 'ATest_AAA_Test'
what is wrong ?
#include <iostream>
#include <gtest/gtest.h>
class A{
public:
int a;
A(int a){this->a = a;}
A(){}
~A(){}
int getA(){return a;}
void setA(int a){this->a = a;}
};
class ATest : public ::testing::Test{
public:
virtual void SetUp(){
a1 = A(1);
a2 = A(2);
a3 = A(3);
}
virtual void TearDwon(){}
A a1;
A a2;
A a3;
};
TEST_F(ATest, AAA){
EXPECT_EQ(1, a1.getA());
EXPECT_EQ(2, a2.getA());
EXPECT_EQ(3, a3.getA());
}
int main(int argc, char **argv){
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

I know this sounds obvious but my psychic debugging skills tell me you forgot to add -lgtest after your object file name when you linked your final binary.

Installing libgtest-dev does not install any of the gtest binaries.
It simply installs the googletest source package on your system - headers
under /usr/include/gtest and source files under /usr/src/gtest,
where you could proceed to build it with cmake or GNU autotools
if you want.
There is no binary package for googletest in ubuntu/debian software channels
(or elsewhere that I know of). The normal practice is to
download the source archive,
extract it and use binaries built by yourself. The README in the
source package gives guidance on building and using the library.
There is normally no purpose in performing a system install of
the source package, as you have done.
The linkage error you have encountered:
undefined reference to 'testing::Test::~Test()
has nothing to do with your code: it occurs because you are not
linking libgtest, and you cannot link it because it is not installed
by libgtest-dev and you have not built it yourself.
This linkage error disappears when you change the code in a way
that introduces a compilation error, because if compilation fails
then linkage does not happen.

Related

Why is the MOCK_METHOD syntax not working in GMock?

I have not even begun testing and I am encountering some syntax issues with GMock's MOCK_METHOD macro even though I am following GMock's documentation properly. Could it be a compiler issue? I have:
MingGW (GCC 4.9.2)
Googletest 1.10.x
class SimpleClass {
public:
virtual int simpleFirstFunction(int a, int b) { return (a + simpleSecondFunction(b)); }
virtual int simpleSecondFunction(int b) { return (2 * b); }
virtual ~SimpleClass();
};
class MockSimpleClass :public SimpleClass {
MOCK_METHOD(int, simpleSecondFunction, (int a, int b), (override));
};
I am seeing 3 compiler errors:
Error-1: about the function name
MockSimpleClass.cpp:18:24: error:
'simpleSecondFunction' is not a type
MOCK_METHOD(int, simpleSecondFunction(int a, int b), (override));
Error-2: about input parameters
MockSimpleClass.cpp:18:46: error:
expected identifier before '(' token
MOCK_METHOD(int, simpleSecondFunction, (int a, int b), (override));
Error-3: About parentheses around "override"
MockSimpleClass.cpp:18:60: error:
expected identifier before '(' token
MOCK_METHOD(int, simpleSecondFunction(int a, int b), (override));
MOCK_METHOD macro is not defined.
Here is how I troubleshooted the exact same issue:
Check preprocessor: gcc -E s1.cpp > s1.preproc.
First of all check the gmock.h included.
In my case it was:
72396 # 11 "s1.cpp" 2
72397 # 1 "/usr/include/gmock/gmock.h" 1 3 4
As you can see a system header is included.
I wen to check googletest version on system(Ubuntu 19.10):
doliaru#host:~/test/gtest/build$ dpkg -l google*
rc google-mock:amd64 1.8.1-3 aand using C++ mock classes
ii googletest:amd64 1.8.1-3 amd64 Google's C++ test frame
dpoliaru#host:~/test/gtest/build$
Apparently this feature was not implemented in 1.8.
I cloned the most recent version of googletest here.
Having checked the topmost CMakeLists.txt on master branch I see that
current gtest version on master is:
set(GOOGLETEST_VERSION 1.10.0)
And I built it with these cmake configs:
cmake .. -D CMAKE_INSTALL_PREFIX=/home/dpoliaru/.local/ -D gtest_build_samples=TRUE
After installation, gmock, that I needed for the project was here:
/home/dpoliaru/.local/include/gmock/gmock.h
Thus, I updated CMakeLists.txt file of the project with the proper include directory for given target:
...
target_include_directories(${PROJECT_NAME} PUBLIC ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS})
...
If you are new to cmake, please check their webpage and find lots of great stuff in cmake-data debian package.
After cmake configure step I see this definition in flags.cmake file:
CXX_INCLUDES = -I/home/dpoliaru/.local/include
With proper include paths I managed to compile the project.
Hope that helps.
It sounds like the MOCK_METHOD macro is not defined. Have you set up your include path correctly and added the #include "gmock/gmock.h" directive at the top of your file? You are also missing a public access specifier and the number of arguments is wrong for the function.
This should work if you have the gmock headers on your include path:
#include "gmock/gmock.h"
class SimpleClass {
public:
virtual int simpleFirstFunction(int a, int b) { return (a + simpleSecondFunction(b)); }
virtual int simpleSecondFunction(int b) { return (2 * b); }
virtual ~SimpleClass();
};
class MockSimpleClass : public SimpleClass {
public:
MOCK_METHOD(int, simpleSecondFunction, (int b), (override));
};

Can't link C++ methods in same source file using Gradle

I'm trying to use Gradle (5.6.2) to build a basic C++ library, and cannot figure out what is going wrong here. I started out using Gradle init to create the basic structure... here's my build.gradle:
plugins {
// Apply the cpp-library plugin to add support for building C++ libraries
id 'cpp-library'
// Apply the cpp-unit-test plugin to add support for building and running C++ test executables
id 'cpp-unit-test'
}
// Set the target operating system and architecture for this library
library {
targetMachines.add(machines.macOS.x86_64)
dependencies {
implementation files('/usr/local/lib/libjsoncpp.a') // used by classA
}
}
tasks.withType(CppCompile).configureEach {
compilerArgs.add "-std=c++11"
compilerArgs.add "-w"
}
The source tree looks like this:
src/main/cpp -> classA.cpp classB.cpp classB.hpp hello.cpp
src/main/public -> classA.hpp cppd.h cpplib.h
src/test/cpp -> classATest.cpp hello_test.cpp
hello.cpp, cppd.h, cpplib.h, and hello_test.cpp all came from the 'gradle init' and aren't actually used.
classA calls a few methods in classB. classB only depends on standard libraries.
classB has a public method classB::method1() that calls two private methods classB::method2() and classB::method3()
When I build, I get a linker error that it can't find classB::method2() or classB::method3(). I checked the method signatures and they all match up (same number and type of arguments in classB.hpp, classB.cpp, and in the linker error message).
I've scoured the Gradle documentation and Googled everything I can think of, tried several variations on the build.gradle file, and... I don't understand why the linker can't find methods in the same CPP file??
Building with Clang 11.0 on MacOS 10.14.6 in case it matters...
Also for reference, here's the relevant bits of the header file:
class classB {
public:
method1();
private:
string& method2(const string& s, bool b);
int method3(uint16_t* b, const string& s);
}
And the methods from the cpp file:
string& method2(const string& s, bool b) {
// blah
}
int method3(uint16_t* b, const string& s) {
// blah
}
OH MY GOODNESS! Just... Nevermind. You know how sometimes posting the question itself is enough to make the problem obvious?
For the record, of course what's missing is the class identifyer-thing (sorry, can't recall the term, I'm coming back from Java) on the front of the method names in the CPP file. They should be:
string& classB::method2(const string& s, bool b) {
// blah
}
int classB::method3(uint16_t* b, const string& s) {
// blah
}
Without the class identifyer-things, the linker doesn't realize they are member functions, and doesn't make the connection.

C++ linked classes weird behaviour

The following code represents the strategy design pattern.
Consider the following program structure:
//base.hpp
#ifndef BASE_HPP
#define BASE_HPP
class Base {
public:
virtual ~Base() {};
virtual int solve() = 0;
};
#endif
//derived.hpp
#include "base.hpp"
class Derived: public Base {
public:
virtual int solve() { return 77; }
};
I have a client.cpp which receives a context of Derived
#include "client.hpp"
#include <iostream>
void Client::operate() {
std::cout << solver_.solve() << std::endl;
}
This is the header file of client:
#include "base.hpp"
class Client {
public:
Client(Base& b): solver_(b) {}
void operate();
private:
Base& solver_;
};
My main: test.cpp
#include "client.hpp"
#include "derived.hpp"
int main() {
Derived d;
Client c(d);
c.operate() ;
}
I would expect it to print 77, but the program doesn't print anything at all.
Client receives a context to Derived by it's constructor and stores it as Base& solver_;
First, the operate method of Client is called, which calls the appropriate solve method of class that derives from Base. In this case, Derived.
Right, that should output 77, but it doesn't. The program compiles fine and no errors, just clean exit. Any ideas ?
I compiled it using following command:
g++ -o program.exe client.cpp test.cpp
I'm using GCC version 5.3.0
I found the solution. The problem was that some of the libraries were not linked by g++, namely libstdc++-6.dll.
This problem can be fixed by using -static-libgcc -static-libstdc++ options
The definition gives:
"When the g++ program is used to link a C++ program, it normally automatically links against libstdc++. If libstdc++ is available as a shared library, and the -static option is not used, then this links against the shared version of libstdc++. That is normally fine. However, it is sometimes useful to freeze the version of libstdc++ used by the program without going all the way to a fully static link. The -static-libstdc++ option directs the g++ driver to link libstdc++ statically, without necessarily linking other libraries statically."
See: libstdc++-6.dll not found

Gtest and Gmock - double free or corruption

I've wasted many hours to resolve this problem, but without success. At first, my configuration: Ubuntu 16.04.1, qmake 3.0, cmake 3.5.1, shared gtest and gmock libraries, version 1.8.0. I use Qt Creator, and this is a little example of minimal program that lead to the crush.
main.cpp:
#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using namespace std;
class A {
void print() {
std::cout << "PRINT" << std::endl;
}
};
class B: public A {
MOCK_METHOD0(print, void());
};
TEST(MOCK, TEST) {
B b;
}
int main(int argc, char *argv[])
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
google_test.pro:
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
LIBS += -lgtest -lgmock
Tests are OK, but at the end of program I get this error:
* Error in `/home/aminought/QtProjects/build-google_test-Desktop_Qt_5_7_0_GCC_64bit-Debug/google_test': double free or corruption (!prev): 0x0000000001a51270 *
How to fix this error? Very annoying.
This problem occurs only with google test compiled as shared libraries. I don't know why, but simple replacement of shared libraries to static solves the problem.
It's been a few years since this was posted.
I could not recreate the exact problem you are having,
but recently I have come across the same error message, in
a different scenario.
The problem was, that I purposely made an override to
TearDown(), freeing a protected member of a fixture class,
which resulted in double freeing pointers. It seems that
googletest is keeping track of allocated memory and tries
to free everything automatically, even though my TearDown()
override already did previously. Removing the override solved
the problem for me.
I hope it will be useful for someone sometime in the future.
In my case, dynamic linking did not have any effect.

Googletest Parametrized tests crash

I've just learned about value-parametrized unit tests in googletest and would like to use them in my project.
I wrote a simple parametrized test.
Header:
#include <gtest/gtest.h>
namespace EnsembleClustering {
class ParametrizedGTest: public testing::TestWithParam<int> {
public:
ParametrizedGTest();
virtual ~ParametrizedGTest();
};
} /* namespace EnsembleClustering */
Source:
#include "ParametrizedGTest.h"
namespace EnsembleClustering {
ParametrizedGTest::ParametrizedGTest() {
// TODO Auto-generated constructor stub
}
ParametrizedGTest::~ParametrizedGTest() {
// TODO Auto-generated destructor stub
}
TEST_P(ParametrizedGTest, testParameter) {
int n = GetParam();
EXPECT_EQ(n, GetParam());
}
INSTANTIATE_TEST_CASE_P(ParametrizedGTestInstance,
ParametrizedGTest,
::testing::Values(100));
} /* namespace EnsembleClustering */
Now, when I run googletest as usual, the program crashes without any output. The gdb stack trace is
EnsembleClustering-D [C/C++ Application]
EnsembleClustering
Thread [1] (Suspended : Signal : EXC_BAD_ACCESS:Could not access memory)
__gnu_debug::_Safe_sequence_base::_M_attach_single() at 0x100528add
__gnu_debug::_Safe_sequence_base::_M_attach() at 0x100528a74
__gnu_debug::_Safe_iterator_base::_M_attach() at 0x100528bfe
__gnu_debug::_Safe_iterator_base::_Safe_iterator_base() at safe_base.h:90 0x1000016e9
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<testing::internal::ParameterizedTestCaseInfoBase**, std::__cxx1998::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> > >, std::__debug::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> > >::_Safe_iterator() at safe_iterator.h:154 0x100002e9c
std::__debug::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> >::begin() at vector:207 0x100001fbe
testing::internal::ParameterizedTestCaseRegistry::GetTestCasePatternHolder<EnsembleClustering::ParametrizedGTest>() at gtest-param-util.h:574 0x1000025b0
EnsembleClustering::ParametrizedGTest_testParameter_Test::AddToRegistry() at ParametrizedGTest.cpp:22 0x100001d3f
__static_initialization_and_destruction_0() at ParametrizedGTest.cpp:22 0x100001349
_GLOBAL__sub_I_ParametrizedGTest.cpp() at ParametrizedGTest.cpp:32 0x100001424
<...more frames...>
gdb
Am I doing something wrong or is this a bug in googletest? Can you reproduce this error?
EDIT: I am on Mac OS X 10.8.
From looking at the source code of gtest the only case if there are no parametrized tests available is on Windows using VC7.1 with disabled exceptions:
// We don't support MSVC 7.1 with exceptions disabled now. Therefore
// all the compilers we care about are adequate for supporting
// value-parameterized tests.
#define GTEST_HAS_PARAM_TEST 1
So, you'll need to check how your MinGW was built and probably update it? And can you run the gtest unit tests to see if they execute the typed parameters test?
More information on MinGW:
On their FAQ they report that when using MinGW the following compile option for building gtest is required: PATH/TO/configure CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin".
Complete Example:
#include <gtest/gtest.h>
namespace EnsembleClustering {
class ParametrizedGTest: public testing::TestWithParam<int> {
public:
ParametrizedGTest();
virtual ~ParametrizedGTest();
};
ParametrizedGTest::ParametrizedGTest() {
}
ParametrizedGTest::~ParametrizedGTest() {
}
TEST_P(ParametrizedGTest, testParameter) {
int n = GetParam();
EXPECT_EQ(n, GetParam());
}
INSTANTIATE_TEST_CASE_P(ParametrizedGTestInstance,
ParametrizedGTest,
::testing::Values(100));
} /* namespace EnsembleClustering */
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
I compiled this code using the following compiler call on Mac OS X 10.8:
g++ -IGTEST_INCLUDE_DIR -LGTEST_LIB_DIR -lgtest -o tt2 tt2.cpp
Where GTEST_INCLUDE_DIR and GTEST_LIB_DIR are the path where header and library files are stored. When you compile and execute, what happens?
Thanks #ChristianStaudt and #grundprinzip
I would like to point future readers to following link that explains this problem.
http://libcwd.sourceforge.net/reference-manual/group__enable__glibcxx__debug.html
This is a link to the documentation for GLIBCXX_DEBUG flag. It states the following important points.
"Note that this flag changes the sizes and behavior of standard class templates such as std::vector, and therefore you can only link code compiled with debug mode and code compiled without debug mode if no instantiation of a container is passed between the two translation units."
"When to use it
It is a good idea to use this if you suspect problems related to iterators."
Now, if you look at the stack trace posted originally, the crash happens due to vector<testing::internal::ParameterizedTestCaseInfoBase*> as gtest tries to get an iterator on this container, using begin() method.
In my case, gtest lib was compiled without GLICXX_DEBUG flag, but my test code was compiled with this flag. The test code worked like a charm when I compiled without this flag.