Stubs and Mocking

Steven J Zeil

Last modified: Feb 27, 2014

1. Stubs

The Lowly Stub

Where ADTs and Stubs Meet

In some ways, ADTs and OOP make it easier to do stubs.

A mock object is an object whose interface emulates a “real” class for testing purposes.

Mock objects may …

Example: Mailing List

In our MailingList tests, we relied on a Contact class.

Here is the real interface for Contact:

contactnmad.h

What Do We Need for the MailingList Test?

But in our tests, the only things we needed to do with contacts was

A Mock Contact

So we made do with a simpler interface that

contact.h

Replacing the Name and Address classes by simple strings.

2. Mock Objects

Object-oriented languages make it easier to create some mock objects

Example: for an application that drew graphics using the Java java.awt.Graphics API, I created the following as a mock class:

GraphicsStub.java

It basically writes each successive graphics call into a string, that can later be examined by unit test cases.

OO Mock Example

Here is a test using that mock:

linesegTest.java

2.1 Mock Frameworks

Increasingly, unit test frameworks are including special support for mock object creation.

Mocking Up an Example

Suppose that we are writing an application that uses this 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;
};

To set up the test of the application code that uses this, we derive a mock class that has the same interface…

A Mock Class

#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_METHOD0(GetX, int());
  MOCK_CONST_METHOD0(GetY, int());
};

Using the Mock

Then in unit tests for the application class, we

  1. use instances of the mock class
  2. Write assertions that describe how we expect the stub to be exercised.
#include "mock-turtle.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using ::testing::AtLeast;

TEST(DrawACircle, CanDrawSomething) {
  MockTurtle turtle;
  EXPECT_CALL(turtle, PenDown())
      .Times(AtLeast(1));
  Painter painter(&turtle);
  EXPECT_TRUE(painter.DrawCircle(0, 0, 10));
}

So, if we call painter.drawCircle(...), we

Stubs can Generate Output

EXPECT_CALL(g, foo(_))
    .TIMES(3)
    .WillRepeatedly(Return(150));
EXPECT_CALL(g, foo(1))
    .WillOnce(Return(100));
EXPECT_CALL(g, foo(2))
    .WillOnce(Return(200));
 

This assertion says

Are Mock Frameworks Useful?