Python:如何模拟多次调用的异步方法?

use*_*861 5 mocking python-3.x python-asyncio

我有一个用于在 Python (3.6) 中测试异步代码的方法:

@asyncio.coroutine
def coroutine_creater(value):
    return value
Run Code Online (Sandbox Code Playgroud)

我这样使用它:

async def test_test():
    my_mock = Mock(return_value=coroutine_creater(5))

    # I call with "await"
    first_call = await my_mock()
    second_call = await my_mock()

    assert first_call == 5, 'first call failed'
    assert second_call == 5, 'second call failed'  # this call fails
Run Code Online (Sandbox Code Playgroud)

这样我就可以为异步调用创建模拟。我发现如果我调用异步方法两次,这不起作用。在我的代码中,first_call如我所料,等于 5,但second_call等于 None。这里发生了什么?如何测试多次调用 Mock 异步方法的代码?

sli*_*wp2 2

您应该设置side_effect的参数Mock

\n
\n

side_effect:每当调用 Mock 时都会调用的函数。请参阅 side_effect 属性。对于引发异常或动态更改返回值很有用。使用与模拟相同的参数调用该函数,除非它返回 DEFAULT,否则该函数的返回值将用作返回值。

\n
\n

下面的示例使用pytest-asynciopytest模块:

\n

code_53856568.py:

\n
import asyncio\n\n\n@asyncio.coroutine\ndef coroutine_creater(value):\n    return value\n
Run Code Online (Sandbox Code Playgroud)\n

test_code_53856568.py:

\n
from unittest.mock import Mock\nfrom code_53856568 import coroutine_creater\nimport pytest\n\n\n@pytest.mark.asyncio\nasync def test_test():\n    def coroutine_creater_side_effect():\n        return coroutine_creater(5)\n\n    my_mock = Mock(side_effect=coroutine_creater_side_effect)\n\n    first_call = await my_mock()\n    second_call = await my_mock()\n\n    assert first_call == 5, \'first call failed\'\n    assert second_call == 5, \'second call failed\'\n
Run Code Online (Sandbox Code Playgroud)\n

带有覆盖率报告的单元测试结果:

\n
(venv) \xe2\x98\x81  python-codelab [master] \xe2\x9a\xa1  coverage run -m pytest /Users/ldu020/workspace/github.com/mrdulin/python-codelab/src/stackoverflow/53856568/test_code_53856568.py && coverage report -m --include="src/*"\n===================================================================================================================== test session starts =====================================================================================================================\nplatform darwin -- Python 3.7.5, pytest-5.3.1, py-1.8.0, pluggy-0.13.1\nrootdir: /Users/ldu020/workspace/github.com/mrdulin/python-codelab\nplugins: asyncio-0.10.0\ncollected 1 item                                                                                                                                                                                                                                              \n\nsrc/stackoverflow/53856568/test_code_53856568.py .                                                                                                                                                                                                      [100%]\n\n====================================================================================================================== 1 passed in 0.04s ======================================================================================================================\nName                                               Stmts   Miss  Cover   Missing\n--------------------------------------------------------------------------------\nsrc/stackoverflow/53856568/code_53856568.py            3      0   100%\nsrc/stackoverflow/53856568/test_code_53856568.py      11      0   100%\n--------------------------------------------------------------------------------\nTOTAL\n
Run Code Online (Sandbox Code Playgroud)\n