What is mockpp
mockpp is a platform independent generic unit testing framework for C++. It's goal is to facilitate developing unit tests in the spirit of Mock Objects for Java, EasyMock and jMock.
Mock objects allow you to set up predictible behaviour to help you test your production code by emulating some functionality your code depends on. This might for example be a huge database which is too difficult and time consuming to maintain just for testing purposes.
Originally I started with a port of Mock Objects to C++ and wanted to keep the same interfaces. But in the meanwhile I found out more about Java and it's differencens to C++ (it's funny reflection api for example ) and so I had to change a bunch of details. Additionally I included the working methods of EasyMock and jMock. From my limited understanding of Java there seems to be something similar in MockObjects but I guess EasyMock is easier to use and certainly was easier to port to C++.
How to use this library
Note: the following sections describe only the basic elements within mockpp. There are also a handbook, an api reference and a tutorial available which explain the various parts of mockpp.
Mockpp contains a number of classes, templates (and macros) which I divide into Basic Expectations and Advanced Expectations.
Basic expectations cover simple actions. You create an object and tell it what is allowed. So if you want to check that a method is passed the correct parameter values you might set up a mock object with an appropriate method like this:
void MyMockClass::methodUnderTest(unsigned i)
If the passed value is 123 as expected everything is fine. Otherwise an AssertionFailedError is thrown.
There are several classes to verify simple expectations:
- verify an exact match
- match a range of values (mainly numerical ones)
- set up a list to verify a series of arbitrary parameters to match one after the other
- verify if objects occur at least once in a collection
- verify substrings
- verify with counter increments
Sometimes you don't want to check ingoing parameters to a method but need predictible objects coming out. In this case you set up a list with return objects:
One object after the other is returned in the given order. If you request one too many object an AssertionFailedError is thrown. The same applies if you don't request all objects.
For more information please refer to the basic section of the developers guide. mockpp currently supports two different approaches to create mock objects. The first is easier to understand but rather strict. The second is more complex but offers more flexibiliy and is extensible with user defined classes. But this is also a matter of personal taste. There is a chapter which introduces into the common characteristics.
The main idea is to replace your real world object with an object that simulates some limited behaviour. For that purpose you create a VisitableMockObject and the according methods. Additionally you record an execution path and feed it some parameters, some objects to return or maybe tell it to throw exceptions. All returned objects and exceptions may also be conditionally based on parameters passed to your method.
To easily feed the expected parameters into your calls you need a mock method for your mock object.
class MyVisitableMockObject : public VisitableMockObject
MyVisitableMockObject(const String &name)
: VisitableMockObject(name, 0)
// constructs an internal mock method
, visitable_mocker("visitable") this)
// forwards the actual call to the mock method
int visitable(unsigned u)
// creates a mock method for: int visitable(unsigned);
VisitableMockMethod<int, unsigned> visitable_mocker;
// create a short hand reference to the mock method
VisitableMockMethod<int, unsigned> &visitor (mvo.visit_mocker);
// we are in record mode now:
visitor.addReturnValue(1); // return "1" the first time
visitor.addReturnValue(11); // return "11" the second time
visitor.setDefaultReturnValue(123); // return "123" all the other calls
visitor.addResponseValue(0, 1); // return "0" when passed "1"
visitor.addResponseValue(1, 0); // return "1" when passed "0"
visitor.addResponseThrowable(make_throwable(int(1), 1); // throw when passed "1"
visitor.addResponseThrowable(make_throwable(int(0), 0); // throw when passed "0"
// throw std::string("string 1") when called the first time
// throw std::string("string 2") the next three times
visitor.addThrowable(std::string("string 2"), 3);
// throw int(123) the rest of the time
mvo.visitable(1); // require "1" as parameter the first time
mvo.visitable(2); // require "2" as parameter the second time
// from now on all calls are verified
mvo.visitable(1); // verify "1" which is ok, see above
mvo.visitable(1); // would fail as "2" is required
For more information please refer to the section about vistable mock objects in the developers guide.
Specifying some behaviour with the second approach called chainable mock objects is similar to describing it in words. You may say for example:
- I expect some method invocation exactly once
- This must happen after another invocation labeled "other-ident"
- The method must be called with with a value which is equal to 321
- Then the method will return 123
- This invocation has an identifier called "ident"
In C++ code you might express the same like this:
Similar to the former approach you must create a helper object to express your expectations. This is further explained in the section about chainable mock objects in the handbook.
Most of the times you don't need a full blown mock objects library. Often some simple lines of code with a quick and dirty approach suffice. For that reason the handbook contains some simple mock object patterns that don't need further support from a library.
If you know some other patterns I would be happy if could send them to me for inclusion into the handbook.
This article is translated to Serbo-Croatian language by Jovana Milutinovich from Webhostinggeeks.com.