0

I'm very new to C++, and I'm trying to use googlemock and googletest. I can't seem to get them to work even in simple examples so I'm sure there must be something simple I'm missing. I would really appreciate some help on this. I have a class Foo which has another class Bar as a dependency so I'm trying to mock this dependency out in tests. I'm sorry in advance, this seems like the simplest Dependency Injection example to me but it still spreads across 9 files! This is Bar:

// lib/bar.h
#ifndef BAR_H
#define BAR_H

class Bar {
  public:
    Bar(int baz);
    virtual ~Bar() {};
    int _baz;
};

#endif

With implementation:

// lib/bar.cpp
#include "bar.h"

Bar::Bar(int baz) : _baz(baz) {}

Here is the MockBar header:

// tests/mock_bar.h
#ifndef MOCK_BAR_H
#define MOCK_BAR_H
#include <gmock/gmock.h>
#include "../lib/bar.h"

class MockBar : public Bar {
  public:
    MockBar();
    virtual ~MockBar() {};
};

#endif

And the implementation:

// tests/mock_bar.cpp
#include "mock_bar.h"

MockBar::MockBar() : Bar(0) {
}

So MockBar is just Bar with baz set to 0. Here is Foo:

// lib/foo.h
#ifndef FOO_H
#define FOO_H
#include "bar.h"

class Foo {
  public:
    Foo(Bar bar);
    virtual ~Foo() {};
    Bar _bar;
    int getBaz();
};

#endif

// lib/foo.cpp
#include "foo.h"

Foo::Foo(Bar bar) : _bar(bar) {
}

int Foo::getBaz() {
  return _bar._baz;
}

And here is my test:

// tests/test_foo.h

#ifndef TEST_FOO_H
#define TEST_FOO_H
#include <gtest/gtest.h>
#include "../lib/foo.h"
#include "mock_bar.h"

class FooTest : public ::testing::Test {
  public:
    FooTest();
    Foo subject;
    MockBar mock_bar;
    virtual ~FooTest() {};
};

#endif

// tests/test_foo.cpp

#include "test_foo.h"

FooTest::FooTest() : mock_bar(), subject(mock_bar) {
}

TEST_F(FooTest, BazTest)
{
  ASSERT_TRUE(subject.getBaz() == 0);
}

Finally, the main test function is:

// tests/main.cpp

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "test_foo.h"

int main(int argc, char **argv) {
  testing::InitGoogleMock(&argc, argv);
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

When I compile this all together with:

g++ tests/main.cpp tests/test_*.cpp tests/mock_*.cpp lib/*.cpp -o test 
-lgtest -lpthread -std=c++11

I get the error:

Undefined symbols for architecture x86_64:
  "testing::InitGoogleMock(int*, char**)", referenced from:
      _main in main-0b53fe.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1

I would really appreciate some help, please let me know if I can be more clear!

dircrys
  • 89
  • 2
  • 8
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Ken White Dec 25 '18 at 23:56
  • The first three undefined symbols seem to be simply because you don't include "lib/*.cpp" in your compilation. I don't know enough about GTest to know what you need to add for the fourth undefined symbol. – R_Kapp Dec 25 '18 at 23:57
  • In the future, please at least do a basic search for the error message before posting. It's highly unlikely you're the first one who has ever seen it. In this case, a simple search for *ld: symbol(s) not found for architecture x86_64* would have found many existing questions here. – Ken White Dec 25 '18 at 23:59
  • Thank you both, I've done what you suggested but I still get a linker error which I think is a googlemock issue... – dircrys Dec 26 '18 at 00:04
  • If either of you want to write an answer I'll accept it, thanks so much for pointing this out. Hard to get into the C++ mindset! – dircrys Dec 26 '18 at 00:06

1 Answers1

0

You are using parts from gmock but only linking gtest. Thats why InitGoogleMock() is undefined.

Replacing -lgtest with -lgmock should make it.

The reason: gtest is testing framework, gmock the mocking framework. If you link gmock, its includes also gtest but not the other way round.

Soeren
  • 1,725
  • 1
  • 16
  • 30