Back to TILs

Google Test

Table of contents

Makefile

A minimal Makefile to build for google-test is shown bellow:

LDFLAGS_GTEST+= -lgtest -lgtest_main -lpthread
LDFLAGS_GMOCK+= -Lgmock -lgmock_main
LDFLAG+= $(LDFLAGS_GTEST) $(LDFLAGS_GMOCK)

all: CheckoutTest

CheckoutTest: CheckoutTest.cpp Checkout.cpp
	$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)

Doubles

Almost all code that gets implemented will depend (i.e. collaborate) on another piece of code in the system.

Those other pieces of code are oftentimes trying to do things or communicate with things that are not available in a unit testing environment or are so slow that they would make our unit tests extremely slow.

Test doubles are the answer to that problem.

They’re objects created in the tests to replace the real production system collaborators.

Dummies

There are many types of test doubles. Dummy objects are the simplest.

They are simply placeholders that are intended to be passed around but not actually called or used in any real way.

They will often generate exceptions if they are called.

class MyDummy : public MyInterface {
  public:
    void SomeFunction() { throw "I should't be called!"; }
};

Fakes

Fake objects have a different and usually simplified implementation from the production collaborator that makes them usable in the test code but not suitable for production.

class MyTestDB : public DBInterface  {
  public:
    void pushData(int data) { dataItems.push_back(data); }
  protected:
    vector<int> dataItems;
};

Stubs

Stubs provide implementations that do expect to be called but respond with basic canned responses.

class MyStub : public MyInterface {
  public:
    int SomeFunction() { return 0; }
};

Spies

Spies provide implementations that record the values that are passed into them. The tests then can use those recorded values for validating the code on our test.

class MySpy : public MyInterface {
  public:
    int savedParam;
    void SomeFunction( int param ) { savedParam = param; }
};

Mocks

Mock objects are the most sophisticated of all the test doubles. They have pre-programmed expectations about the ordering of calls, the number of times functions will be called, and the values that will be passed in.

Mock objects will generate their own exceptions when these pre-programmed expectations are not met.

class MyMock : public MyInterface {
  public:
    void SomeFunction( int param ) {
      if( 1 != param ) {
        throw "I should't be called!";
      }
    }
};

References