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
class asynctest.MagicMock(*args, **kw)[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.

see Mock.

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.

If new isn’t provided, the default is a CoroutineMock if the patched object 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.