1

I have see some sample code about gmock,

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <stdio.h>
#include <string>

class MockFoo {
 public:
  MockFoo() {}

  MOCK_METHOD3(Bar, char(const std::string& s, int i, double x));
  MOCK_METHOD2(Bar2, bool(int x, int y));
  MOCK_METHOD2(Bar3, void(int x, int y));

 private:
  GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
};

class GMockOutputTest : public testing::Test {
 protected:
  MockFoo foo_;
};

TEST_F(GMockOutputTest, ExpectedCall) {
  testing::GMOCK_FLAG(verbose) = "info";

  EXPECT_CALL(foo_, Bar2(0, _));
  foo_.Bar2(0, 0);  // Expected call

  testing::GMOCK_FLAG(verbose) = "warning";
}

The mock class MockFoo is mocking three functions as is in the class body, but the class MockFoo does not inherit any class.

If I understand it correctly, the mock class can mock virtual and non-virtual functions.

1) Mocking virtual functions: mock class should inherit a base class being mocked, and all the functions in that class should be virtual, but in this example, there is no base class.

2) Mocking non-virtual functions: mock class does not need inherit any class, but it needs to add tamplate to the code in order to use hi-perf dependency injection.

Does the code above belong to any of the case? And what is it trying to mock? And how to understand it?

Ian
  • 777
  • 4
  • 15
ratzily
  • 141
  • 1
  • 3
  • 14

2 Answers2

1

The key thing to remember here is that a mock class can override either virtual or non-virtual methods in a superclass, but it doesn't have to. Sometimes it's useful to define a totally standalone mock which doesn't conform to any particular interface or override any other functionality. Consider the case where you are testing a templatized class:

template <typename T>
class Foo {
public:
    Foo(T* member) : _member(member) {}

    void f() { _member->bar(); }

private:
    T* _member;
};

You want to verify that class Foo invokes bar() on the template parameter class, but the template class doesn't need to conform to any formal interface; it just needs to expose a bar() method. In this case you might use a standalone mock:

class MockSomething {
public:
    MOCK_METHOD0(bar, void());
};

Just like your example, this mock class has no relationship to another class or interface. It's a standalone mock, and it can be used just as you would any other:

TEST(StackOverflow, StandaloneMock) {

    MockSomething mock;
    EXPECT_CALL(mock, bar());

    Foo<MockSomething> foo(&mock);
    foo.f();
}
Ian
  • 777
  • 4
  • 15
0

That code is to test the method Bar2() of template class NaggyMock. To be more precise, it is testing that when you call method Bar2() with parameters 0 and 0, that Bar2() method from the mock is going to be called.

You can look at that as a static dependency injection, since you inject dependency through a template parameter. I would say it is the case 2.


Assuming your template class NaggyMock looks like this :

template< typename Foo >
class NaggyMock
{
public:

    bool Bar2(int x, int y)
    {
        if ( ( 0 == x ) && ( 0 == y ) )
        {
            return foo.Bar2( 0, 11 );
        }

        return false;
    }

private:

    Foo foo;
};

then in the unit test you are testing the case when both parameters are 0. If your real class is using some resource (reading from a network, or from a database, or a file, ...), then to avoid it, and make your unit test very fast, you are going to mock that object. And that is what you are doing. Instead of the class handing the real resource, you are injecting a mock object.

For more information, read :

Community
  • 1
  • 1
BЈовић
  • 57,268
  • 38
  • 158
  • 253
  • this mock class MockFoo did not inherit any class, if the MockFoo is mocking the function from NaggyMock, should it inherit NaggyMock class? – ratzily Jan 16 '15 at 15:59
  • @ratzily No. `NaggyMock` is probably creating object of `MockFoo` class, and that is a typical dependency injection. In the production code, you pass the class that does the real thing - not mock. – BЈовић Jan 16 '15 at 16:01
  • ok, but this code is for testing. And I only want to understand how this work for testing. This MockFoo is mocking some functions, for example bar2(). what is this MockFoo mocking? Mocking the functions defined in NaggyMock? – ratzily Jan 16 '15 at 16:17