1 回答

TA貢獻1873條經(jīng)驗 獲得超9個贊
確實,您不能混合使用自動指定和新的可調(diào)用項。相反,可以自動指定方法,然后替換side_effect屬性,并為其指定一個AsyncMock()實例:
from unittest import mock
def configure_coroutine_mock(mock_function, klass=AsyncMock):
"""Make an autospecced async function return a coroutine mock"""
mock_function.side_effect = AsyncMock()
# mark the side effect as a child of the original mock object
# so transitive access is recorded on the parent mock too. This is
# what .return_value does normally
mock._check_and_set_parent(
mock_function.mock, mock_function.side_effect,
None, '()')
return mock_asy_method.side_effect
with mocker.patch('ExampleClass.asy_method', autospec=True) as mock_asy_method:
configure_coroutine_mock(mock_asy_method)
因為AsyncMock()是可調(diào)用的對象,所以每次mock_asy_method調(diào)用都會調(diào)用,并將參數(shù)傳遞給該對象。然后,該調(diào)用的結果用于從返回mock_asy_method():
>>> from unittest import mock
>>> class ExampleClass:
... async def asy_method(self, param):
... return await some_coroutine(self, param)
...
>>> example_instance = ExampleClass()
>>> with mock.patch('__main__.ExampleClass.asy_method', autospec=True) as mock_asy_method:
... configure_coroutine_mock(mock_asy_method)
... print(example_instance.asy_method('foo')) # call to patched class coroutine
... print(mock_asy_method.mock_calls) # calls are recorded
...
<AsyncMock name='asy_method()' id='4563887496'>
<coroutine object AsyncMock.__call__ at 0x1100780f8>
[call(<__main__.ExampleClass object at 0x10ffac1d0>, 'foo')]
如您所見,self參數(shù)和參數(shù)記錄在調(diào)用中,因為這mock_asy_method是一種適當?shù)暮瘮?shù)。
當然,只有在AsyncMock()實際等待返回的呼叫結果時,我們才會看到該呼叫也被記錄:
>>> with mock.patch('__main__.ExampleClass.asy_method', autospec=True) as mock_asy_method:
... configure_coroutine_mock(mock_asy_method)
... loop = asyncio.get_event_loop()
... coro = example_instance.asy_method('foo')
... loop.run_until_complete(coro)
... print(mock_asy_method.mock_calls)
...
<AsyncMock name='asy_method()' id='4564408920'>
<AsyncMock name='asy_method()()' id='4564999360'>
[call(<__main__.ExampleClass object at 0x10ffac1d0>, 'foo'),
call()(<__main__.ExampleClass object at 0x10ffac1d0>, 'foo')]
添加回答
舉報