#python #async-await #pytest #python-asyncio #python-3.8
#python #асинхронное ожидание #pytest #python-asyncio #python-3.8
Вопрос:
У меня есть вопрос новичка о макетном исправлении асинхронного объекта с помощью Python 3.8. Все, что я пытаюсь, это макет post(), чтобы я мог протестировать логику обработки ошибок, но пока мне не повезло. Не могли бы вы сказать мне, что я сделал не так? Большое спасибо.
main.py
import httpx
test_data = {"id": "123"}
class DebugClass:
def post(self):
try:
async with httpx.AsyncClient() as client:
res = await client.post(url='http://localhost:8080', data=test_data)
return "OK"
except Exception as e:
return "NOK"
test_main.py
from unittest import mock
from unittest.mock import patch, AsyncMock
from main import DebugClass
class TestClass:
@mock.patch('httpx.AsyncClient.post', new_callable=AsyncMock)
def test_post(self, mock_client_post):
mock_client_post = AsyncMock(side_effect=TimeoutError)
debug_class = DebugClass()
res = debug_class.post()
assert res == "NOK"
Ответ №1:
Для тестирования asyncio
кода с помощью pytest
я бы посоветовал вам использовать библиотеки pytest-asyncio и asynctest.
Для установки: pip install pytest-asyncio asynctest
.
Ниже приведен пример, основанный на вашем коде:
import httpx
import asynctest
import pytest
class DebugClass:
async def post(self):
try:
async with httpx.AsyncClient() as client:
res = await client.post(url='http://localhost:8080', data=test_data)
return "OK"
except Exception as e:
return "NOK"
@pytest.mark.asyncio
async def test_debug_class_post():
with asynctest.patch('httpx.AsyncClient.post') as post_mock:
post_mock.side_effect = TimeoutError
debug_class = DebugClass()
res = await debug_class.post()
assert res == "NOK"
Комментарии:
1. Большое спасибо за вашу помощь, Алекс! Это работает :)! У меня просто есть еще один вопрос. Когда я запускаю ваш код, pytest вернул это предупреждение: Предупреждение об устаревании: декоратор «@coroutine» устарел с Python 3.8, используйте «async def» вместо def wait(self, skip = 0): Просто из любопытства, есть ли какой-либо альтернативный синтаксис для pytest.mark.asyncio? Спасибо 🙂
2. К сожалению, на сегодняшний
asyntest
день он еще не обновлен для поддержки нового синтаксиса, поэтому я могу только посоветовать вам отключить предупреждение об устаревании3. Отмечено. Спасибо, Алекс.