Python 单元测试 - 如何修补我正在测试的方法内部的异步调用

问题描述 投票:0回答:2

我使用 unittest.mock 为我的 python 代码构建测试。我有一个正在尝试测试的方法,其中包含对另一个函数的异步调用。我想修补该异步调用,以便我可以让 Mock 返回

asset id
的测试值,而不是实际调用异步方法。我已经尝试了很多在网上找到的方法,但到目前为止都没有效果。

以下简化示例:

测试.py

import pytest

from app.create.creations import generate_new_asset
from app.fakeapi.utils import create_asset

from unittest.mock import Mock, patch

@patch("app.fakeapi.utils.create_asset")
@pytest.mark.anyio
async def test_generate_new_asset(mock_create):
    mock_create.return_value = 12345678

    await generate_new_asset()

    ...

创作.py

from app.fakeapi.utils import create_asset
...

async def generate_new_asset()
    ...
    # When I run tests this does not return the 12345678 value, but actually calls the `create_asset` method.
    return await create_asset(...) 
python unit-testing mocking
2个回答
5
投票

测试异步代码有点棘手。如果您使用的是 python3.8 或更高版本

AsyncMock
可用。

注意:它仅适用于

Python > 3.8

我认为在你的情况下事件循环丢失了。这是应该可以工作的代码,您可能需要做一些调整。您可能还需要安装

pytest-mock
。将其作为固定装置将允许您模拟不同的值来测试不同的场景。

import asyncio
from unittest.mock import AsyncMock, Mock

@pytest.fixture(scope="module")
def mock_create_asset(mocker):
   async_mock = AsyncMock()
   mocker.patch('app.fakeapi.utils.create_asset', side_effect=async_mock)
   return async_mock

@pytest.fixture(scope="module")
def event_loop():
    return asyncio.get_event_loop()

 @pytest.mark.asyncio
 async def test_generate_new_asset(mock_create_asset):
    mock_create_asset.return_value = 12345678
    await generate_new_asset() 

0
投票

使用

new_callable=AsyncMock

import pytest

from app.create.creations import generate_new_asset
from app.fakeapi.utils import create_asset

from unittest.mock import Mock, patch, AsyncMock

@patch("app.fakeapi.utils.create_asset", new_callable=AsyncMock)
@pytest.mark.anyio
async def test_generate_new_asset(mock_create):
    mock_create.return_value = 12345678

    await generate_new_asset()

    ...
© www.soinside.com 2019 - 2024. All rights reserved.