Solution 4: Poor Man's Mock Objects

Often, maybe most of the time, you don't need a full-featured mock object library. If you only want to make sure a method is invoked at all a simple boolean flag with a self-made mock object suffices. If you want to track invocation order you might extend this a bit and store a counter value for each method. Each call to any of the methods increments the counter.

Such a mock object may have really little functionality, exactly what is really needed. The following code shows how this could look like.

First the variables are declared. For simplicity all those variables have public access.

class PoorMock : public Interface
{
  public:

    unsigned counter;
    unsigned open_counter;
    unsigned read_counter;
    unsigned write_counter;
    unsigned close_counter;

The constructor resets all the variables for determined results:

    PoorMock()
    {
      counter = 0;
      open_counter = 0;
      read_counter = 0;
      write_counter = 0;
      close_counter = 0;
    }

Then each method invocation stores the current counter value in the according variable and increments the counter afterwards.

    virtual void open(const std::string &name)
    {
      open_counter = ++counter;
    }

If a method returns a value it may suffice to return the same value all the time if the method is only called once. Otherwise a simple array or a std::vector might already provide enough convenience for a set of values.

    virtual std::string read()
    {
      read_counter = ++counter;
      return "dummy";
    }

After the methods have been invokedin the test the according counters are checked for the expected value. Since this approach is really simple it may become necessary to check more often to better locate problems. The asserter may also be simple and terminate the application after printing the error.

  Consumer consumer(&mock);
  consumer.load();

  ASSERTER(mock.open_counter == 1);
  ASSERTER(mock.read_counter == 4);
  ASSERTER(mock.close_counter == 5);

  consumer.process();
  consumer.save();

  ASSERTER(mock.open_counter == 6);
  ASSERTER(mock.write_counter == 9);
  ASSERTER(mock.close_counter == 10);

poormock.cpp contains the complete source code.

Next: Solution 5: Poor Man's Mock Objects, Second Edition

Table of contents

 All Classes Namespaces Files Functions Variables Typedefs Friends Defines

Generated on Tue Jan 5 18:03:33 2010 for mockpp-tutorial by  doxygen 1.6.1