Как я могу макетировать ответы, сделанные aiohttp.ClientSession?

Я использую aiohttp для выполнения асинхронных запросов и хочу проверить свой код. Я хочу макетировать запросы, отправленные aiohttp.ClientSession. Я ищу что-то похожее на то, как ответы обрабатывают насмешки для requests Lib.

Как я могу высказать ответы, сделанные aiohttp.ClientSession?

# sample method
async def get_resource(self, session):
    async with aiohttp.ClientSession() as session:
        response = await self.session.get("some-external-api.com/resource")
        if response.status == 200:
            result = await response.json()
            return result

        return {...}

# I want to do something like ...
aiohttp_responses.add(
    method='GET', 
    url="some-external-api.com/resource", 
    status=200, 
    json={"message": "this worked"}
)

async def test_get_resource(self):
    result = await get_resource()
    assert result == {"message": "this worked"}
  • Я попробовал aioresponses, но примеры не работали для меня.
  • Я прочитал документы по тестированию aiohttp. Кажется, они охватывают макетирование входящих запросов на ваш веб-сервер, но я не уверен, что это помогает мне макетировать ответы на исходящие запросы

3 ответа

  1. создать фиктивный ответ
class MockResponse:
    def __init__(self, text, status):
        self._text = text
        self.status = status

    async def text(self):
        return self._text

    async def __aexit__(self, exc_type, exc, tb):
        pass

    async def __aenter__(self):
        return self
  1. использовать pytest mocker для имитации запроса
@pytest.mark.asyncio
async def test_exchange_access_token(self, mocker):
    data = {}

    resp = MockResponse(json.dumps(data), 200)

    mocker.patch('aiohttp.ClientSession.post', return_value=resp)

    resp_dict = await account_api.exchange_access_token('111')

Поскольку я разместил этот вопрос, я использовал эту библиотеку для имитации запросов aiohttp: https://github.com/pnuckowski/aioresponse, и она хорошо сработала для моих нужд.

  1. Создайте функцию, которая вернет ваш издевательский ответ:
      async def create_resp(status_code=200, resp_data=None):
    resp = mock.AsyncMock(status_code=status_code)
    resp.json.return_value = resp_data
    return resp
  1. Затем используйте его в своем тесте:
      @pytest.mark.asyncio
@mock.patch('ms_printers.clients.menu.aiohttp.ClientSession.get')
async def test_ok(self, mock_get):
    mock_get.return_value = create_resp(resp_data={'a': 1})
Другие вопросы по тегам