【问题标题】:How can I mock functions that are called by async code?如何模拟由异步代码调用的函数?
【发布时间】:2020-12-21 19:22:23
【问题描述】:

这个测试有效。

def test_mock_ingest():
    with mock.patch('app.ingest.ingest') as mock_ingest:
        app.ingest.ingest('test-data', {'test-key': 'test-value'})
        assert mock_ingest.call_count == 1

此测试失败,因为mock_ingest.call_count = 0

def test_mock_ingest():
    with mock.patch('app.ingest.ingest') as mock_ingest:
        call_function_that_runs_async_code()
        assert mock_ingest.call_count == 1

call_function_that_runs_async_code 调用app.ingest.ingest 函数。

我知道是因为我可以看到测试数据已被摄取。

但由于某种原因,mock_ingest.call_count 仍然是 0。

我认为这与运行 app.ingest.ingest 的代码是异步的这一事实有关。

编辑:

我正在使用 python 3.8。

我也试过了,但没有成功:

```python
def test_mock_ingest():
    with mock.patch('app.ingest.ingest', new_callable=mock.AsyncMock) as mock_ingest:
        call_function_that_runs_async_code()
        assert mock_ingest.call_count == 1

【问题讨论】:

  • 您是否尝试过以下操作? def test_mock_ingest(): with patch.object(app.ingest, 'ingest') as mock_ingest: call_function_that_runs_async_code() mock_ingest.assert_called_once()
  • 这能回答你的问题吗? Mocking async call in python 3.5
  • @DolevP 是的,但我在某处读到该方法存在陷阱,因此我改用 call_count
  • @code11 我也在 python 3.8 中尝试过new_callable=mock.AsyncMock。将其添加到我的问题中。
  • 我明白了。我的观点不仅仅是使用assert_called_once() 代替call_count,而是使用patch.object 代替patch

标签: python python-asyncio python-3.8


【解决方案1】:

该解决方案毕竟与异步代码无关。

call_function_that_runs_async_code 没有打电话给app.ingest.ingest

ingest 像这样导入后调用ingestfrom app.ingest import ingest

该导入是正确的,但由于模拟的命名空间问题,跨应用程序代码和测试代码以不同方式导入函数不起作用。

直到您在导入它们的地方修补函数,而不是在定义它们的地方。 https://docs.python.org/3/library/unittest.mock.html#where-to-patch

我的示例中正确的解决方案代码应如下所示:

def test_mock_ingest():
    with mock.patch('async_codebase.ingest') as mock_ingest:
        call_function_that_runs_async_code()
        assert mock_ingest.call_count == 1

其中async_codebase 包含导入:

from app.ingest import ingest

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-16
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    • 2019-06-15
    • 2022-12-07
    相关资源
    最近更新 更多