Usage

The mocker fixture has the same API as mock.patch, supporting the same arguments:

import os


def test_foo(mocker):
    # all valid calls
    mocker.patch('os.remove')
    mocker.patch.object(os, 'listdir', autospec=True)
    mocked_isfile = mocker.patch('os.path.isfile')

The supported methods are:

Also, as a convenience, these names from the mock module are accessible directly from mocker:

It is also possible to use mocking functionality from fixtures of other scopes using the appropriate fixture:

  • class_mocker

  • module_mocker

  • package_mocker

  • session_mocker

Spy

The mocker.spy object acts exactly like the original method in all cases, except the spy also tracks function/method calls, return values and exceptions raised.

def test_spy_method(mocker):
    class Foo(object):
        def bar(self, v):
            return v * 2

    foo = Foo()
    spy = mocker.spy(foo, 'bar')
    assert foo.bar(21) == 42

    spy.assert_called_once_with(21)
    assert spy.spy_return == 42

def test_spy_function(mocker):
    # mymodule declares `myfunction` which just returns 42
    import mymodule

    spy = mocker.spy(mymodule, "myfunction")
    assert mymodule.myfunction() == 42
    assert spy.call_count == 1
    assert spy.spy_return == 42

The object returned by mocker.spy is a pytest_mock.SpyType object which subclasses MagicMock, so all standard checking functions are available (like assert_called_once_with or call_count in the examples above), in addition to four extra attributes:

  • spy_return: contains the last returned value of the spied function.

  • spy_return_iter: contains a duplicate of the last returned value of the spied function if the value was an iterator and spy was created using .spy(..., duplicate_iterators=True). Uses tee) to duplicate the iterator.

  • spy_return_list: contains a list of all returned values of the spied function (new in 3.13).

  • spy_exception: contain the last exception value raised by the spied function/method when it was last called, or None if no exception was raised.

mocker.resetall() sets these attributes back to their initial values.

Besides functions and normal methods, mocker.spy also works for class and static methods.

As of version 3.0.0, mocker.spy also works with async def functions.

Note

In versions earlier than 2.0, the attributes were called return_value and side_effect respectively, but due to incompatibilities with unittest.mock they had to be renamed (see #175 for details).

As of version 3.10, spying can be also selectively stopped.

def test_with_unspy(mocker):
    class Foo:
        def bar(self):
            return 42

    spy = mocker.spy(Foo, "bar")
    foo = Foo()
    assert foo.bar() == 42
    assert spy.call_count == 1
    mocker.stop(spy)
    assert foo.bar() == 42
    assert spy.call_count == 1

mocker.stop() can also be used by mocker.patch calls.

Stub

The stub is a mock object that accepts any arguments and is useful to test callbacks. It may receive an optional name that is shown in its repr, useful for debugging.

def test_stub(mocker):
    def foo(on_something):
        on_something('foo', 'bar')

    stub = mocker.stub(name='on_something_stub')

    foo(stub)
    stub.assert_called_once_with('foo', 'bar')

Async stub

Use mocker.async_stub() for an asynchronous callback. It returns an AsyncMock, so calling it creates an awaitable. The call is recorded as soon as the stub is called, so call assertions such as assert_called_once_with pass even before the awaitable is awaited. Use assert_awaited_once_with to verify that the callback was awaited with the expected arguments.

For example, with pytest-asyncio:

import pytest

@pytest.mark.asyncio
async def test_async_stub(mocker):
    stub = mocker.async_stub(name="on_something_stub")

    pending = stub("foo", "bar")
    stub.assert_called_once_with("foo", "bar")
    stub.assert_not_awaited()

    await pending
    stub.assert_awaited_once_with("foo", "bar")

Do not use called or call_count alone to check that an asynchronous callback was awaited. await_count and the assert_awaited* methods track awaits separately.

Resetting mocks

mocker.resetall() calls reset_mock() on the mocks created through mocker so far: those from mocker.patch (and its variants), mocker.spy and mocker.create_autospec. Mocks created with mocker.stub(), mocker.async_stub() or mocker.Mock() and the other aliases are not tracked, so they are not reset.

import os


def test_reset(mocker):
    listdir = mocker.patch("os.listdir", return_value=["foo"])
    os.listdir("/tmp")

    mocker.resetall()
    listdir.assert_not_called()
    assert os.listdir("/tmp") == ["foo"]

    mocker.resetall(return_value=True, side_effect=True)
    assert os.listdir("/tmp") != ["foo"]

By default only the recorded calls are reset. Pass return_value=True and/or side_effect=True to also reset those, as with reset_mock().

Some kinds of patches are handled specially:

  • mocker.patch.multiple: every mock it patched in is reset, both the ones it created and the ones passed explicitly.

  • mocker.patch.dict: the patched dictionary and its values are left alone.

  • mocker.spy: the spy_return, spy_return_iter, spy_return_list and spy_exception attributes are set back to their initial values. With side_effect=True, the spy goes back to calling the spied code instead of having its side_effect set to None, clearing any side_effect set on the spy.

Usage as context manager

Although mocker’s API is intentionally the same as mock.patch’s, its use as context manager and function decorator is not supported through the fixture:

def test_context_manager(mocker):
    a = A()
    with mocker.patch.object(a, 'doIt', return_value=True, autospec=True):  # DO NOT DO THIS
        assert a.doIt() == True

The purpose of this plugin is to make the use of context managers and function decorators for mocking unnecessary, so it will emit a warning when used as such.

If you really intend to mock a context manager, mocker.patch.context_manager exists which won’t issue the above warning.

Where to patch

A common issue where mocking appears not to be working is patching in the wrong place.

See this section in the unittest docs which provides a comprehensive explanation.

Also see this excellent blog post: Why your mock doesn’t work.