Overview of the pMock API

Creating mocks

A mock object is created to represent a real object for the purposes of a unit test. Using a mock object rather than the real object can be useful if the real object is difficult to construct, hasn't been written yet or causes awkward side effects in use.
    import pmock
    ...
    mock = pmock.Mock()
Expectations are defined for the methods that are meant to be called on the mock object.
    mock.expects(pmock.once()).render()
The mock can now be called with the expected method.
    mock.render()
Calling the mock with unexpected methods causes an exception to be raised.

When the mock objects have been set up, they are then used in the unit test as the real objects would have been.

    pictures = [mock]
    gallery = Gallery(pictures)
    gallery.render()
After the test's normal assertions have been made, an assertion that the mock's expectations have been satisfied should be made.
    mock.verify()
If any of the mock's expectations haven't been satisfied, such as an expected method not having been called, then the verify call raises an exception.

Argument expectations

Expectations can be set on the arguments passed to the mock's methods.
    mock.expects(pmock.once()).render(pmock.eq(640), pmock.eq(480))
The arguments to the expectation's mocked method are constraint objects which are evaluated on the actual arguments when a call is made to the mock object. If an argument doesn't satisfy its constraint then the expectation remains unsatisfied.
    mock.expects(pmock.once()).render(brush=pmock.same(print.BIG_BRUSH))
More flexible argument constraints can be defined using a slightly more verbose set of methods.
    mock.expects(pmock.once()).method("render") # any arguments allowed
    mock.expects(pmock.once()).method("render").with_at_least(brush=pmock.same(print.BIG_BRUSH))

Number of calls to the same method

The argument to the expects method describes how often the expected method can be called.
    mock.expects(pmock.once()).boil()
    mock.expects(pmock.at_least_once()).simmer()
    mock.expects(pmock.never()).fry()

Call order expectations

The order of calls to the mock object can be described with the after method.
    mock.expects(pmock.once()).invalidate()
    mock.expects(pmock.once()).render().after("invalidate")

An explicit id can be set for an expectation and used in the after method instead of using the method name.

    mock.expects(pmock.once()).add(pmock.eq(10)).id("add #1")
    mock.expects(pmock.once()).add(pmock.eq(15)).id("add #2").after("add #1")
    mock.expects(pmock.once()).add(pmock.eq(5)).after("add #2")
The order of calls can also be defined across different mock objects.
    other_mock = pmock.Mock()
    other_mock.expects(pmock.once()).add()
    mock = pmock.Mock()
    mock.expects(pmock.once()).sum().after("add", other_mock)

Mock behaviour

The mocked methods can be provided with simple behaviours using the will method.
    mock.expects(pmock.once()).calculate().will(pmock.return_value(20))
    mock.expects(pmock.once()).consume().will(pmock.raise_exception(RuntimeError("invalid")))

Stubs

Stubs allow behaviours to be specified for methods that can be called any number of times and are not to be included in the mock's verification check.
    mock.stubs().sleep().will(pmock.return_value(True))

Default behaviour for undefined methods

When an undefined method is called an exception is normally raised. However this behviour can be overridden by supplying a stub object to the Mock instance's set_default_stub method.
    mock.set_default_stub(pmock.return_value("legs"))
    mock.crazy()

From imports

The test code can be made more concise by importing the pmock module's public classes and functions into the test module.
    from pmock import *

    mock = Mock()
    mock.expects(once()).calculate(eq(34), eq(2)).will(return_value(68))

Test base class

The MockTestCase class is a convenience base class for tests. It provides the mock method for creating mock objects that will be automatically verified after the test method has run. The verify calls are made to the mock object after tearDown has been called.
    class FooTest(pmock.MockTestCase):

        def test_involving_mocks(self):
            bar = self.mock()
            bar.expects(pmock.once()).baz()
            qux.quux(bar)
            # no need for verify call as its done by MockTestCase

Further information

Looking at the pMock acceptance tests may be helpful in further clarifying the behaviour of the module.

The mock objects and jmock websites contain useful information on mock objects and their use as a testing technique.

Martin Fowler has written an interesting article about mock objects and the style of unit testing that uses them.