我使用 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(...)
测试异步代码有点棘手。如果您使用的是 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()
使用
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()
...