<p>子类化<code>MagicMock</code>将为从协同程序模拟生成的所有模拟传播自定义类。例如,<code>AsyncMock().__str__</code>也会变成一个<code>AsyncMock</code>,这可能不是你想要的。</p>
<p>相反,您可能需要定义一个工厂,它使用自定义参数创建<code>Mock</code>(或<code>MagicMock</code>),例如<code>side_effect=coroutine(coro)</code>。此外,将协程函数与协程分离(如<a href="https://docs.python.org/3/library/asyncio-task.html#coroutines" rel="noreferrer">documentation</a>中所述)可能是一个好主意。</p>
<p>以下是我想到的:</p>
<pre><code>from asyncio import coroutine
def CoroMock():
coro = Mock(name="CoroutineResult")
corofunc = Mock(name="CoroutineFunction", side_effect=coroutine(coro))
corofunc.coro = coro
return corofunc
</code></pre>
<p>对不同对象的解释:</p>
<ul>
<li><code>corofunc</code>:协程函数模拟</li>
<li><code>corofunc.side_effect()</code>:为每个调用生成的协程</li>
<li><code>corofunc.coro</code>:协同程序用于获取结果的模拟</li>
<li><code>corofunc.coro.return_value</code>:协程返回的值</li>
<li><code>corofunc.coro.side_effect</code>:可能用于引发异常</li>
</ul>
<p>示例:</p>
<pre><code>async def coro(a, b):
return await sleep(1, result=a+b)
def some_action(a, b):
return get_event_loop().run_until_complete(coro(a, b))
@patch('__main__.coro', new_callable=CoroMock)
def test(corofunc):
a, b, c = 1, 2, 3
corofunc.coro.return_value = c
result = some_action(a, b)
corofunc.assert_called_with(a, b)
assert result == c
</code></pre>