Mock objects

Wrapper to unittest.mock reducing the boilerplate when testing asyncio powered code.

A mock can behave as a coroutine, as specified in the documentation of Mock.

Mock classes

class asynctest.Mock(spec=None, side_effect=None, return_value=sentinel.DEFAULT, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, **kwargs)[source]

Enhance unittest.mock.Mock so it returns a CoroutineMock object instead of a Mock object where a method on a spec or spec_set object is a coroutine.

For instance:

>>> class Foo:
...     @asyncio.coroutine
...     def foo(self):
...         pass
...
...     def bar(self):
...         pass
>>> type(asynctest.mock.Mock(Foo()).foo)
<class 'asynctest.mock.CoroutineMock'>
>>> type(asynctest.mock.Mock(Foo()).bar)
<class 'asynctest.mock.Mock'>

The test author can also specify a wrapped object with wraps. In this case, the Mock object behavior is the same as with an unittest.mock.Mock object: the wrapped object may have methods defined as coroutine functions.

If you want to mock a coroutine function, use CoroutineMock instead.

See NonCallableMock for details about asynctest features, and unittest.mock for the comprehensive documentation about mocking.

class asynctest.NonCallableMock(spec=None, wraps=None, name=None, spec_set=None, is_coroutine=None, parent=None, **kwargs)[source]

Enhance unittest.mock.NonCallableMock with features allowing to mock a coroutine function.

If is_coroutine is set to True, the NonCallableMock object will behave so asyncio.iscoroutinefunction() will return True with mock as parameter.

If spec or spec_set is defined and an attribute is get, CoroutineMock is returned instead of Mock when the matching spec attribute is a coroutine function.

The test author can also specify a wrapped object with wraps. In this case, the Mock object behavior is the same as with an unittest.mock.Mock object: the wrapped object may have methods defined as coroutine functions.

See unittest.mock.NonCallableMock

is_coroutine

True if the object mocked is a coroutine

class asynctest.MagicMock(*args, **kwargs)[source]

Enhance unittest.mock.MagicMock so it returns a CoroutineMock object instead of a Mock object where a method on a spec or spec_set object is a coroutine.

If you want to mock a coroutine function, use CoroutineMock instead.

MagicMock allows to mock __aenter__, __aexit__, __aiter__ and __anext__.

When mocking an ansynchronous iterator, you can set the return_value of __aiter__ to an iterable to define the list of values to be returned during iteration.

You can not mock __await__. If you want to mock an object implementing __await__, CoroutineMock will likely be sufficient.

see Mock.

New in version 0.11: support of asynchronous iterators and asynchronous context managers.

class asynctest.CoroutineMock(*args, **kwargs)[source]

Enhance Mock with features allowing to mock a coroutine function.

The CoroutineMock object will behave so the object is recognized as coroutine function, and the result of a call as a coroutine:

>>> mock = CoroutineMock()
>>> asyncio.iscoroutinefunction(mock)
True
>>> asyncio.iscoroutine(mock())
True

The result of mock() is a coroutine which will have the outcome of side_effect or return_value:

  • if side_effect is a function, the coroutine will return the result of that function,
  • if side_effect is an exception, the coroutine will raise the exception,
  • if side_effect is an iterable, the coroutine will return the next value of the iterable, however, if the sequence of result is exhausted, StopIteration is raised immediately,
  • if side_effect is not defined, the coroutine will return the value defined by return_value, hence, by default, the coroutine returns a new CoroutineMock object.

If the outcome of side_effect or return_value is a coroutine, the mock coroutine obtained when the mock object is called will be this coroutine itself (and not a coroutine returning a coroutine).

The test author can also specify a wrapped object with wraps. In this case, the Mock object behavior is the same as with an unittest.mock.Mock object: the wrapped object may have methods defined as coroutine functions.

Patch

asynctest.GLOBAL = <PatchScope.GLOBAL: 2>

Value of scope, activating a patch until the decorated generator or coroutine returns or raises an exception.

asynctest.LIMITED = <PatchScope.LIMITED: 1>

Value of scope, deactivating a patch when a decorated generator or a coroutine pauses (yield or await).

asynctest.patch(target, new=sentinel.DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, scope=<PatchScope.GLOBAL: 2>, **kwargs)[source]

A context manager, function decorator or class decorator which patches the target with the value given by ther new argument.

new specifies which object will replace the target when the patch is applied. By default, the target will be patched with an instance of CoroutineMock if it is a coroutine, or a MagicMock object.

It is a replacement to unittest.mock.patch(), but using asynctest.mock objects.

When a generator or a coroutine is patched using the decorator, the patch is activated or deactivated according to the scope argument value:

  • asynctest.GLOBAL: the default, enables the patch until the generator or the coroutine finishes (returns or raises an exception),
  • asynctest.LIMITED: the patch will be activated when the generator or coroutine is being executed, and deactivated when it yields a value and pauses its execution (with yield, yield from or await).

The behavior differs from unittest.mock.patch() for generators.

When used as a context manager, the patch is still active even if the generator or coroutine is paused, which may affect concurrent tasks:

@asyncio.coroutine
def coro():
    with asynctest.mock.patch("module.function"):
        yield from asyncio.get_event_loop().sleep(1)

@asyncio.coroutine
def independent_coro():
    assert not isinstance(module.function, asynctest.mock.Mock)

asyncio.create_task(coro())
asyncio.create_task(independent_coro())
# this will raise an AssertionError(coro() is scheduled first)!
loop.run_forever()
Parameters:scopeasynctest.GLOBAL or asynctest.LIMITED, controls when the patch is activated on generators and coroutines

When used as a decorator with a generator based coroutine, the order of the decorators matters. The order of the @patch() decorators is in the reverse order of the parameters produced by these patches for the patched function. And the @asyncio.coroutine decorator should be the last since @patch() conceptually patches the coroutine, not the function.

@patch(“module.function2”) @patch(“module.function1”) @asyncio.coroutine def test_coro(self, mock_function1, mock_function2):

yield from asyncio.get_event_loop().sleep(1)

see unittest.mock.patch().

New in version 0.6: patch into generators and coroutines with a decorator.

asynctest.patch.object(target, attribute, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, scope=asynctest.GLOBAL, **kwargs)

Patch the named member (attribute) on an object (target) with a mock object, in the same fashion as patch().

See patch() and unittest.mock.patch.object().

asynctest.patch.multiple(target, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, scope=asynctest.global, **kwargs)

Perform multiple patches in a single call. It takes the object to be patched (either as an object or a string to fetch the object by importing) and keyword arguments for the patches.

See patch() and unittest.mock.patch.multiple().

asynctest.patch.dict(in_dict, values=(), clear=False, scope=asynctest.GLOBAL, **kwargs)

Patch a dictionary, or dictionary like object, and restore the dictionary to its original state after the test.

Its behavior can be controlled on decorated generators and coroutines with scope.

New in version 0.8: patch into generators and coroutines with a decorator.

Parameters:
  • in_dict – dictionary like object, or string referencing the object to patch.
  • values – a dictionary of values or an iterable of (key, value) pairs to set in the dictionary.
  • clear – if True, in_dict will be cleared before the new values are set.
  • scopeasynctest.GLOBAL or asynctest.LIMITED, controls when the patch is activated on generators and coroutines
See:

patch() (details about scope) and unittest.mock.patch.dict().

Helpers

asynctest.mock_open(mock=None, read_data='')[source]

A helper function to create a mock to replace the use of open(). It works for open() called directly or used as a context manager.

Parameters:
  • mock – mock object to configure, by default a MagicMock object is created with the API limited to methods or attributes available on standard file handles.
  • read_data – string for the read() and readlines() of the file handle to return. This is an empty string by default.
asynctest.return_once(value, then=None)[source]

Helper to use with side_effect, so a mock will return a given value only once, then return another value.

When used as a side_effect value, if one of value or then is an Exception type, an instance of this exception will be raised.

>>> mock.recv = Mock(side_effect=return_once(b"data"))
>>> mock.recv()
b"data"
>>> repr(mock.recv())
'None'
>>> repr(mock.recv())
'None'
>>> mock.recv = Mock(side_effect=return_once(b"data", then=BlockingIOError))
>>> mock.recv()
b"data"
>>> mock.recv()
Traceback BlockingIOError
Parameters:
  • value – value to be returned once by the mock when called.
  • then – value returned for any subsequent call.

New in version 0.4.