Mocking with gMock
==================



C++ is an object-oriented language. C++ objects live in a "society", they
communicate with other objects with the same or different type.


Communication:

- sending messages
- receiving responses



State-based testing (gtest)

 - is good for testing how the object responds to messages
 - not that good for testing when sending messages



We replace the communication partners with fake/mock objects to test
the BEHAVIOR of the object.


Problems with dependencies:

  - communication may be non-deterministic (e.g. time related)
  - can be flaky
  - difficult/expensive to create or reproduce (e.g. database)
  - slow
  - hard to simulate failures
  - not exists yet


Mock object allows you to check teh interaction between itself
and the user (teh code we test)

A mock class

  - has the same interface then the real
  - can control the behavior at run time
  - verify interactions


How to create mock objects?

  - By hand?
  - Automatically  (jMock, EasyMock using reflection)
      - in C++, we have no reflection
        therefore gMock is nor a transcript of jMock/EasyMock

  Different design choices:

  - Macros
  - DSL for expectations and actions


   MOCK_METHODn( name, type );    // n is the #argsof method


  class Foo
  {
    virtual void DoThis() = 0;
    virtual bool DoThat( int n, double x) = 0;
  };


  class MockFoo : pucblic Foo
  {
    MOCK_METHOD0( DoThis, void());
    MOCK_METHOD2( DoThat, bool(int n, double x));
  };

  MockFoo mock_foo;


  The mock interface should answer:

  - Which methods were called?
  - What arguments?
  - How many times?
  - Which order?
  - What responses?


  mock_foo.DoThat(n,x)

  - will be called
  - with a positive n
  - twice
  - returning true first time, returning false second time.


Described in the DSL:


  MockFoo mock_foo;

  EXPECT_CALL(mock_foo, DoThat( Gt(0), _ ))
                .Times(2)
                .WillOnce(Return(true))
                .WillOnce(Return(false));

  server.xyz( &mock_foo );


Anywhere this fails, we immediately got the info (e.g. stacktrace).


Matchers
--------


Matchers are predicates

  Gt(0)
  _

  User can create arbitrary matchers.


Matcher are composable

  EXPECT_CALL( mock_turtle,
               goTo(0, AllOf(Gt(0), Lt(10)))
             );



Cardinalities
-------------


  Times(2)
  Times(AtLeast(3))  // not too tightly coupled to implementation




Actions (optional)
------------------


  If they are not given, default actions will be taken.


  Return(true)


  DoAll( action1, ..., actionN);  // sequence of actions
  ReturnRef(object);
  Invoke(function)



Simulating failures
-------------------


  EXPECT_CALL( mock_file, Read( _, 256))
                 .Times(AtLeast(3))
                 .WillOnce(Return(256))
                 .WillOnce(Return(256))
                 .WillRepeatedly(Return(0));


Testing logs
------------


  ScopedMockLog  log;  // with constructor and destructor

  EXPECT_CALL( log, Log(INFO, "path/to/foo.cc", HasSubstr("Foo")))
                    .Times(AtLeast(1));



Order of calls
--------------


  Strict sequence order (total order):


  {  // create a block

    InSequence s;  // any name 

    EXPECT_CALL(...);
    EXPECT_CALL(...);
    EXPECT_CALL(...);

  }


  Also partial order
  Also can express any DAG



  gMock is extensible





IMPLEMENTATION DETAILS
======================


MOCK_METHOD2( DoThat, bool(int n, double x));


MOCK_METHOD3( Foo,
              bool( char (*fp)(),
                    char s[5],
                    map<int, string> m)
            );



SAMPLE
======



/* turtle.h */
/* Turtle abstract base class */
class Turtle {
  virtual ~Turtle() {}
  virtual void PenUp() = 0;
  virtual void PenDown() = 0;
  virtual void Forward(int distance) = 0;
  virtual void Turn(int degrees) = 0;
  virtual void GoTo(int x, int y) = 0;
  virtual int GetX() const = 0;
  virtual int GetY() const = 0;
};



/* painter.h */
#ifndef PAINTER_H
#define PAINTER_H

#include "turtle.h"

class Painter
{
public:
  Painter( Turtle *trt);
  bool DrawCircle(int x, int y, int r);
private:
  Turtle *turtle;
};

#endif /* PAINTER_H */



/* painter.cpp */
#include "painter.h"

Painter::Painter( Turtle *trt) : turtle(trt) { }

bool Painter::DrawCircle( int x, int y, int r)
{
  return true;
}




/* mock_turtle.h */
/* The Mock Turtle */
#include <gmock/gmock.h>

class MockTurtle : public Turtle
{
public:
  MOCK_METHOD0( PenUp, void() );
  MOCK_METHOD0( PenDown, void() );
  MOCK_METHOD1( Forward, void (int distance) );
  MOCK_METHOD1( Turn, void (int degrees) );
  MOCK_METHOD2( GoTo, void (int x, int y) );
  MOCK_CONST_METHOD( GetX, int () );
  MOCK_CONST_METHOD( GetY, int () );
};



One can use the gmock_gen.py script to generate the mock class.


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

#include "painter.h"
#include "mock_turtle.h"

using ::testing::AtLeast;

TEST(PainterTest, PenDownBeforeDraw)
{
  MockTurtle turtle;
  EXPECT_CALL(turtle, PenDown())
      .Times(AtLeast(1));

  Painter painter(&turtle);

  EXPECT_TRUE(painter.DrawCircle(0, 0, 10));
}

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



$ g++ -std=c++11 -pedantic -Wall -W -I../../googletest/googletest/include/
-I../../googletest/googlemock/include/ painter.cpp  test1.cpp
../../lib/libgmock.a -pthread -o test1


$ ./test1
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from PainterTest
[ RUN      ] PainterTest.PenDownBeforeDraw
test1.cpp:13: Failure
Actual function call count doesn't match EXPECT_CALL(turtle, PenDown())...
         Expected: to be called at least once
           Actual: never called - unsatisfied and active
[  FAILED  ] PainterTest.PenDownBeforeDraw (0 ms)
[----------] 1 test from PainterTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] PainterTest.PenDownBeforeDraw

 1 FAILED TEST



Fix it in painter.cpp:

/* painter.cpp */
#include "painter.h"

Painter::Painter( Turtle *trt) : turtle(trt) { }

bool Painter::DrawCircle( int x, int y, int r)
{
  turtle->PenDown();
  return true;
}


$ ./test1
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from PainterTest
[ RUN      ] PainterTest.PenDownBeforeDraw
[       OK ] PainterTest.PenDownBeforeDraw (0 ms)
[----------] 1 test from PainterTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.




The generic form of the EXPECT_CALL is:

  EXPECT_CALL(mock_object, method(matchers))
      .With(multi_argument_matcher)
      .Times(cardinality)
      .InSequence(sequences)
      .After(expectations)
      .WillOnce(action)
      .WillRepeatedly(action)
      .RetiresOnSaturation();



Times
=====


If Times() is omitted the default is:

  - Times(1)  when neither WillOnce nor WillRepeatedly specified
  - Times(n)  when n WillOnes and no WillRepeatedly specified (n>=1)
  - Times(AtLeast(n)) when n WillOnes and a WillRepeatedly specified (n>=0)

Times(0) means the method must not be called.


Cardinalities are:

AnyNumber()
AtLeast(n)
AtMost(n)
Between(m, n)
Exactly(n)
n
0



Matchers
========


Are used inside EXPECT_CALL() or directly:

EXPECT_THAT( value, matcher)
ASSERT_THAT( value, matcher)  // fatal


Wildcard
--------

  _   underscore:          any value of the correct type

  A<type>()  An<type>()    any value of "type"



Comparison
----------

Eq(value)
 value                 arg == value
Ge(value)              arg >= value
Gt(value)
Le(value)
Lt(value)
Ne(value)
IsNull()               null ptr (raw or smart)
NotNull()              not null ptr (raw or smart)
Ref(variable)          arg is reference
TypedEq<type>(value)   arg has type "type" and equal to value


These matchers (except Ref) make copy of value. If type of value is
not copyable, try byRef(), e.q.

  Eq(ByRef(non_copyable_value))


DoubleEq(dvalue)    NaNs are unequal.
FloatEq(fvalue)
NanSensitiveDoubleEq(dvalue)  NaNs are equal.
NanSensitiveFloatEq(fvalue)


DoubleNear(dvalue, maxerr)
...


ContainsRegex(string)
EndsWith(suffix)
HasSubstr(string)
MatchesRegex(string)   matches from first to last pos.
StartsWith(prefix)
StrCaseEq(string)      ignoring case
StrCaseNeq(string)     ignoring case
StrEq(string)
StrNe(string)



Container matchers
------------------


STL containers can be checked with Eq, since they support ==

Contains(e)   Argument containes element e, e can be a further matcher
Each(e)       Every element matches e
ElementsAre(e0, e1, ..., en)  (max 0..10 arguments)
AlementsAreArray(...)  values coming from C array, init list, STL container
IsEmpty()
SizeIs(m)
UnorderedElementsAre(e0, e1, ..., en)
WhenSorted(m)
WhenSortedBy(comparator,m)



Member matchers
---------------


Field( &class:field, m)     argobj.field or argptr->field matches m
Key(e)                      arg.first matches e  e.g. Contains(Key(Le(5)))
Pair(m1,m2)                 std::pair, first matches m1, second matches m2



Functor
-------

ResultOf(f,m)   f function/functor, f(args) matches m



Pointer
-------

Pointee(m)      arg is (raw or smart) pointer pointing something matches m
WhenDynamicCastTo<T>(m)    dynamic_cast<T>(arg) matches m



Composite matchers
------------------

AllOf(m1, m2, ..., mN)   mathes all of m1 ... mN
AnyOf(m1, m2, ..., mN)   at least one
Not(m)                   does not match m



User defined matchers
---------------------


- MATCHER macros must be used outside a function or class
- must not be side effect
- PrintToString(x) converts x value to string


MATCHER(IsEven, "") { return (arg % 2) == 0; }



ACTIONS
=======


Return()                    void
Return(value)
ReturnArg<N>()	            N-th arg
ReturnNew<T>(a1, ..., ak)   new T(a1,...,ak)
ReturnNull()
ReturnPointee(ptr)
ReturnRef(variable)
ReturnRefOfCopy(value)      coyp lives as long as action


Assign(&variable, value)
DeleteArg<N>()
SaveArg<N>(pointer)         *pointer = N-th arg
...
Throw(exception)

Invoke(f)                  call f with args passed to mock function
Invoke(object_pointer, &class::method)
InvokeWithoutArgs(f)
InvokeWithoutArgs(object_pointer, &class::method)




Expectation order
=================


using ::testing::Expectation;

Expectation init_x = EXPECT_CALL(foo, InitX());
Expectation init_y = EXPECT_CALL(foo, InitY());

EXPECT_CALL(foo, Bar())
    .After(init_x, init_y);




using ::testing::ExpectationSet;

ExpectationSet all_inits;
for (int i = 0; i < element_count; i++)
{
  all_inits += EXPECT_CALL(foo, InitElement(i));
}

EXPECT_CALL(foo, Bar())
    .After(all_inits);




Sequences
=========


First Reset() than any of GetSize() or Describe():

using ::testing::Sequence;
Sequence s1, s2;

EXPECT_CALL(foo, Reset())
    .InSequence(s1, s2)
    .WillOnce(Return(true));
EXPECT_CALL(foo, GetSize())
    .InSequence(s1)
    .WillOnce(Return(1));
EXPECT_CALL(foo, Describe(A<const char*>()))
    .InSequence(s2)
    .WillOnce(Return("dummy"));



Strict order:

using ::testing::InSequence;
{
  InSequence dummy;

  EXPECT_CALL(...)...;
  EXPECT_CALL(...)...;
  ...
  EXPECT_CALL(...)...;
}





#ifndef PAINTER_H
#define PAINTER_H

#include "turtle.h"

class Painter
{
public:
  Painter( Turtle *trt);
  bool DrawCircle(int x, int y, int r);
  bool DrawZigzag(int n);
private:
  Turtle *turtle;
};

#endif /* PAINTER_H */



#include "painter.h"

Painter::Painter( Turtle *trt) : turtle(trt) { }

bool Painter::DrawCircle( int x, int y, int r)
{
  turtle->PenDown();
  return true;
}

bool Painter::DrawZigzag(int n)
{
  turtle->PenDown();
  for (int i = 0; i < n; ++i)
  {
    turtle->Turn(10);
    turtle->Forward(5);
  }
  return true;
}



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

#include "painter.h"
#include "mock_turtle.h"

using ::testing::AtLeast;
using ::testing::Ge;

TEST(PainterTest, PenDownBeforeDraw)
{
  MockTurtle turtle;
  EXPECT_CALL(turtle, PenDown())
      .Times(AtLeast(1));

  Painter painter(&turtle);

  EXPECT_TRUE(painter.DrawCircle(0, 0, 10));
}

TEST(PainterTest, XwithZigzag)
{
  MockTurtle turtle;
  EXPECT_CALL(turtle, Forward(Ge(2)))
      .Times(AtLeast(3));

  Painter painter(&turtle);

  EXPECT_TRUE(painter.DrawZigzag(4));
}

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



$ ./test1
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from PainterTest
[ RUN      ] PainterTest.PenDownBeforeDraw
[       OK ] PainterTest.PenDownBeforeDraw (0 ms)
[ RUN      ] PainterTest.XwithZigzag

GMOCK WARNING:
Uninteresting mock function call - returning directly.
    Function call: PenDown()
NOTE: You can safely ignore the above warning unless this call should not happen.  Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call.  See http://code.google.com/p/googlemock/wiki/CookBook#Knowing_When_to_Expect for details.

GMOCK WARNING:
Uninteresting mock function call - returning directly.
    Function call: Turn(10)
NOTE: You can safely ignore the above warning unless this call should not happen.  Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call.  See http://code.google.com/p/googlemock/wiki/CookBook#Knowing_When_to_Expect for details.

[       OK ] PainterTest.XwithZigzag (0 ms)
[----------] 2 tests from PainterTest (0 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[  PASSED  ] 2 tests.



This warning can be surpressed by using:

    NiceMock<MockTurtle>

instead of

    MockTurtle





/* painter.h */
#ifndef PAINTER_H
#define PAINTER_H

#include "turtle.h"

class Painter
{
public:
  Painter( Turtle *trt);
  bool DrawLine(int len);
  bool DrawZigzag(int n);
private:
  Turtle *turtle;
};

#endif /* PAINTER_H */


/* painter.cpp */
#include "painter.h"

Painter::Painter( Turtle *trt) : turtle(trt) { }

bool Painter::DrawLine( int len)
{
  turtle->PenDown();
  turtle->Forward(len);
  turtle->PenUp();
  return true;
}

bool Painter::DrawZigzag(int n)
{
  turtle->PenDown();
  for (int i = 0; i < n; ++i)
  {
    turtle->Turn(10);
    turtle->Forward(5);
  }
  return true;
}



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

#include "painter.h"
#include "mock_turtle.h"

using ::testing::AtLeast;
using ::testing::Ge;
using ::testing::InSequence;
using ::testing::_;

TEST(PainterTest, PenDownBeforeDraw)
{
  NiceMock<MockTurtle> turtle;
  EXPECT_CALL(turtle, PenDown())
      .Times(AtLeast(1));

  Painter painter(&turtle);

  EXPECT_TRUE(painter.DrawLine(10));
}

TEST(PainterTest, XwithZigzag)
{
  NiceMock<MockTurtle> turtle;
  EXPECT_CALL(turtle, Forward(Ge(2)))
      .Times(AtLeast(3));

  Painter painter(&turtle);

  EXPECT_TRUE(painter.DrawZigzag(4));
}

TEST(PainterTest, DrawLineSequence)
{
  MockTurtle turtle;
  {
    InSequence dummy;

    EXPECT_CALL(turtle, PenDown());
    EXPECT_CALL(turtle, Forward(_));
    EXPECT_CALL(turtle, PenUp());
  }

  Painter painter(&turtle);
  painter.DrawLine(4);
}

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


$ ./test2
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from PainterTest
[ RUN      ] PainterTest.PenDownBeforeDraw
[       OK ] PainterTest.PenDownBeforeDraw (0 ms)
[ RUN      ] PainterTest.XwithZigzag
[       OK ] PainterTest.XwithZigzag (1 ms)
[ RUN      ] PainterTest.DrawLineSequence
[       OK ] PainterTest.DrawLineSequence (0 ms)
[----------] 3 tests from PainterTest (1 ms total)

[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (1 ms total)
[  PASSED  ] 3 tests.




STATE MAINTENANCE
=================


Suppose we have a configurator class:


class Configurator
{
public:
  virtual ~Configurator() {}

  virtual void setParamX(int n) = 0;
  virtual int getParamX() = 0;
};


And we have a client class using configurator:

class Client
{
public:
  Client(Configurator &cfg);
  virtual ~Client() {}

  void setParamX(int n);
  void incParamXBy(int n);
  int getParamX();
private:
  Configurator & _cfg;
};


void Client::incParamXBy(int n)
{
  _cfg.setParamX(_cfg.getParamX() + n);
}



Suppose that the initial value of paramX is A.
We want to increase paramX by B each time we call incParamXBy.

Our expectation is that if incParamXBy is called for the first time,
it will result in calling cfg.setParamX(A+B).

second call of incParamXBy(B) will result in calling cfg.setPAramX(A + 2*B)

third call: cfg.setPAramX(A + 3*B), and so on...


Since the Client behavior relies on Configurator, to test Client
the Configurator should remember the previous paramX value:
should store a state.



class MockConfigurator : public Configurator
{
public:
  int paramX;
  int * paramX_ptr;

  MockConfigurator()
  {
    paramX = 0;
    paramX_ptr = &paramX;
  }

  MOCK_METHOD1(setParamX, void(int n));
  MOCK_METHOD0(getParamX, int());
};


We put the state into MockConfigurator. (We could store it as a global
value too, but this is more maintainable).


Here is the full program:



/* configurator.h */
#ifndef CONFIGURATOR_H
#define CONFIGURATOR_H

class Configurator
{
public:
  virtual ~Configurator() {}

  virtual void setParamX(int n) = 0;
  virtual int getParamX() = 0;
};

#endif /* CONFIGURATOR_H */


/* mock_configurator.h */
#ifndef MOCK_CONFIGURATOR
#define MOCK_CONFIGURATOR

#include <gmock/gmock.h>

#include "configurator.h"

class MockConfigurator : public Configurator
{
public:
  int paramX;
  int *paramX_ptr;

  MockConfigurator()
  {
    paramX = 0;
    paramX_ptr = &paramX;
  }

  MOCK_METHOD1(setParamX, void(int n));
  MOCK_METHOD0(getParamX, int());
};

#endif /* MOCK_CONFIGURATOR */


/* client.h */
#ifndef CLIENT_H
#define CLIENT_H

class Client
{
public:
  Client(Configurator &cfg) : _cfg(cfg) {};
  virtual ~Client() {}

  void setParamX(int n);
  void incParamXBy(int n);
  int getParamX();
private:
  Configurator & _cfg;
};

#endif /* CLIENT_H */


/* client.cpp */
#include "configurator.h"
#include "client.h"

void Client::incParamXBy(int n)
{
  _cfg.setParamX(_cfg.getParamX() + n);
}



/* test1.cpp */
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "mock_configurator.h"
#include "client.h"

using namespace testing;

TEST(PainterTest, PenDownBeforeDraw)
{
  MockConfigurator cfg;
  Client client(cfg);

  int inc_value = 10;

  // getParamX will be called a number of times.
  // If it is called, we will return the value pointed to by paramX_ptr.
  // Returning with ReturnPointee is necessary, since we need to have
  // the actual (updated) value each time the method is called.
  EXPECT_CALL(cfg, getParamX())
      .Times(AnyNumber())
      .WillRepeatedly(ReturnPointee(cfg.paramX_ptr));

  // SaveArg stores the 0th parameter of the call 
  // in the value pointed to by paramX_ptr (paramX)
  // expectation 3
  EXPECT_CALL(cfg, setParamX(cfg.paramX + 3*inc_value))
      .Times(1)
      .WillOnce(DoAll(SaveArg<0>(cfg.paramX_ptr), Return()));
  // expectation 2
  EXPECT_CALL(cfg, setParamX(cfg.paramX + 2*inc_value))
      .Times(1)
      .WillOnce(DoAll(SaveArg<0>(cfg.paramX_ptr), Return()));
  // expectation 1
  EXPECT_CALL(cfg, setParamX(cfg.paramX + inc_value))
      .Times(1)
      .WillOnce(DoAll(SaveArg<0>(cfg.paramX_ptr), Return()));

  client.incParamXBy(inc_value); //this will match expectation 1
  client.incParamXBy(inc_value); //this will match expectation 2
  client.incParamXBy(inc_value); //this will match expectation 3
}

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


$ ./test1
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from PainterTest
[ RUN      ] PainterTest.PenDownBeforeDraw
[       OK ] PainterTest.PenDownBeforeDraw (0 ms)
[----------] 1 test from PainterTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (1 ms total)
[  PASSED  ] 1 test.



Other options:
--------------

 -  We could use precalculated values (no state is required)
 -  We could use Invoce action