bpo-26467: Adds AsyncMock for asyncio Mock library support (GH-9296) · python/cpython@77b3b77
@@ -201,9 +201,11 @@ The Mock Class
201201202202.. testsetup::
203203204+ import asyncio
205+ import inspect
204206 import unittest
205207 from unittest.mock import sentinel, DEFAULT, ANY
206- from unittest.mock import patch, call, Mock, MagicMock, PropertyMock
208+ from unittest.mock import patch, call, Mock, MagicMock, PropertyMock, AsyncMock
207209 from unittest.mock import mock_open
208210209211:class:`Mock` is a flexible mock object intended to replace the use of stubs and
@@ -851,6 +853,217 @@ object::
851853 >>> p.assert_called_once_with()
852854853855856+.. class:: AsyncMock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs)
857+858+ An asynchronous version of :class:`Mock`. The :class:`AsyncMock` object will
859+ behave so the object is recognized as an async function, and the result of a
860+ call is an awaitable.
861+862+>>> mock = AsyncMock()
863+>>> asyncio.iscoroutinefunction(mock)
864+True
865+>>> inspect.isawaitable(mock())
866+True
867+868+ The result of ``mock()`` is an async function which will have the outcome
869+ of ``side_effect`` or ``return_value``:
870+871+ - if ``side_effect`` is a function, the async function will return the
872+ result of that function,
873+ - if ``side_effect`` is an exception, the async function will raise the
874+ exception,
875+ - if ``side_effect`` is an iterable, the async function will return the
876+ next value of the iterable, however, if the sequence of result is
877+ exhausted, ``StopIteration`` is raised immediately,
878+ - if ``side_effect`` is not defined, the async function will return the
879+ value defined by ``return_value``, hence, by default, the async function
880+ returns a new :class:`AsyncMock` object.
881+882+883+ Setting the *spec* of a :class:`Mock` or :class:`MagicMock` to an async function
884+ will result in a coroutine object being returned after calling.
885+886+>>> async def async_func(): pass
887+ ...
888+>>> mock = MagicMock(async_func)
889+>>> mock
890+<MagicMock spec='function' id='...'>
891+>>> mock()
892+<coroutine object AsyncMockMixin._mock_call at ...>
893+894+ .. method:: assert_awaited()
895+896+ Assert that the mock was awaited at least once.
897+898+>>> mock = AsyncMock()
899+>>> async def main():
900+ ... await mock()
901+ ...
902+>>> asyncio.run(main())
903+>>> mock.assert_awaited()
904+>>> mock_2 = AsyncMock()
905+>>> mock_2.assert_awaited()
906+Traceback (most recent call last):
907+ ...
908+AssertionError: Expected mock to have been awaited.
909+910+ .. method:: assert_awaited_once()
911+912+ Assert that the mock was awaited exactly once.
913+914+>>> mock = AsyncMock()
915+>>> async def main():
916+ ... await mock()
917+ ...
918+>>> asyncio.run(main())
919+>>> mock.assert_awaited_once()
920+>>> asyncio.run(main())
921+>>> mock.method.assert_awaited_once()
922+Traceback (most recent call last):
923+ ...
924+AssertionError: Expected mock to have been awaited once. Awaited 2 times.
925+926+ .. method:: assert_awaited_with(*args, **kwargs)
927+928+ Assert that the last await was with the specified arguments.
929+930+>>> mock = AsyncMock()
931+>>> async def main(*args, **kwargs):
932+ ... await mock(*args, **kwargs)
933+ ...
934+>>> asyncio.run(main('foo', bar='bar'))
935+>>> mock.assert_awaited_with('foo', bar='bar')
936+>>> mock.assert_awaited_with('other')
937+Traceback (most recent call last):
938+ ...
939+AssertionError: expected call not found.
940+Expected: mock('other')
941+Actual: mock('foo', bar='bar')
942+943+ .. method:: assert_awaited_once_with(*args, **kwargs)
944+945+ Assert that the mock was awaited exactly once and with the specified
946+ arguments.
947+948+>>> mock = AsyncMock()
949+>>> async def main(*args, **kwargs):
950+ ... await mock(*args, **kwargs)
951+ ...
952+>>> asyncio.run(main('foo', bar='bar'))
953+>>> mock.assert_awaited_once_with('foo', bar='bar')
954+>>> asyncio.run(main('foo', bar='bar'))
955+>>> mock.assert_awaited_once_with('foo', bar='bar')
956+Traceback (most recent call last):
957+ ...
958+AssertionError: Expected mock to have been awaited once. Awaited 2 times.
959+960+ .. method:: assert_any_await(*args, **kwargs)
961+962+ Assert the mock has ever been awaited with the specified arguments.
963+964+>>> mock = AsyncMock()
965+>>> async def main(*args, **kwargs):
966+ ... await mock(*args, **kwargs)
967+ ...
968+>>> asyncio.run(main('foo', bar='bar'))
969+>>> asyncio.run(main('hello'))
970+>>> mock.assert_any_await('foo', bar='bar')
971+>>> mock.assert_any_await('other')
972+Traceback (most recent call last):
973+ ...
974+AssertionError: mock('other') await not found
975+976+ .. method:: assert_has_awaits(calls, any_order=False)
977+978+ Assert the mock has been awaited with the specified calls.
979+ The :attr:`await_args_list` list is checked for the awaits.
980+981+ If *any_order* is False (the default) then the awaits must be
982+ sequential. There can be extra calls before or after the
983+ specified awaits.
984+985+ If *any_order* is True then the awaits can be in any order, but
986+ they must all appear in :attr:`await_args_list`.
987+988+>>> mock = AsyncMock()
989+>>> async def main(*args, **kwargs):
990+ ... await mock(*args, **kwargs)
991+ ...
992+>>> calls = [call("foo"), call("bar")]
993+>>> mock.assert_has_calls(calls)
994+Traceback (most recent call last):
995+ ...
996+AssertionError: Calls not found.
997+Expected: [call('foo'), call('bar')]
998+>>> asyncio.run(main('foo'))
999+>>> asyncio.run(main('bar'))
1000+>>> mock.assert_has_calls(calls)
1001+1002+ .. method:: assert_not_awaited()
1003+1004+ Assert that the mock was never awaited.
1005+1006+>>> mock = AsyncMock()
1007+>>> mock.assert_not_awaited()
1008+1009+ .. method:: reset_mock(*args, **kwargs)
1010+1011+ See :func:`Mock.reset_mock`. Also sets :attr:`await_count` to 0,
1012+:attr:`await_args` to None, and clears the :attr:`await_args_list`.
1013+1014+ .. attribute:: await_count
1015+1016+ An integer keeping track of how many times the mock object has been awaited.
1017+1018+>>> mock = AsyncMock()
1019+>>> async def main():
1020+ ... await mock()
1021+ ...
1022+>>> asyncio.run(main())
1023+>>> mock.await_count
1024+1
1025+>>> asyncio.run(main())
1026+>>> mock.await_count
1027+2
1028+1029+ .. attribute:: await_args
1030+1031+ This is either ``None`` (if the mock hasn’t been awaited), or the arguments that
1032+ the mock was last awaited with. Functions the same as :attr:`Mock.call_args`.
1033+1034+>>> mock = AsyncMock()
1035+>>> async def main(*args):
1036+ ... await mock(*args)
1037+ ...
1038+>>> mock.await_args
1039+>>> asyncio.run(main('foo'))
1040+>>> mock.await_args
1041+call('foo')
1042+>>> asyncio.run(main('bar'))
1043+>>> mock.await_args
1044+call('bar')
1045+1046+1047+ .. attribute:: await_args_list
1048+1049+ This is a list of all the awaits made to the mock object in sequence (so the
1050+ length of the list is the number of times it has been awaited). Before any
1051+ awaits have been made it is an empty list.
1052+1053+>>> mock = AsyncMock()
1054+>>> async def main(*args):
1055+ ... await mock(*args)
1056+ ...
1057+>>> mock.await_args_list
1058+[]
1059+>>> asyncio.run(main('foo'))
1060+>>> mock.await_args_list
1061+[call('foo')]
1062+>>> asyncio.run(main('bar'))
1063+>>> mock.await_args_list
1064+[call('foo'), call('bar')]
1065+1066+8541067Calling
8551068~~~~~~~
8561069