Python 如何使用aioresponses模拟ClientSession,而不将会话作为参数传入

Python 如何使用aioresponses模拟ClientSession,而不将会话作为参数传入,python,mocking,aiohttp,Python,Mocking,Aiohttp,我尝试使用模拟ClientSession POST请求。但我无法连接到主机服务器。我只是使用aiohttp客户端,而不是服务器。另外,我不想将伪会话作为参数传递给测试函数。有办法做到这一点吗?我认为应该使用aioresponses来模拟远程主机端点的整个url 让我们假设,我们将模拟外部服务,如电报机器人API服务器。我们想测试发送POST请求的客户端库ClientTgBot的sendMessage方法 我们的项目结构如下: /app - __init__.py - client_tgbot

我尝试使用模拟ClientSession POST请求。但我无法连接到主机服务器。我只是使用aiohttp客户端,而不是服务器。另外,我不想将伪会话作为参数传递给测试函数。有办法做到这一点吗?

我认为应该使用aioresponses来模拟远程主机端点的整个url

让我们假设,我们将模拟外部服务,如电报机器人API服务器。我们想测试发送POST请求的客户端库ClientTgBot的sendMessage方法

我们的项目结构如下:

/app
 - __init__.py
 - client_tgbot.py
/tests/
 - __init_.py
 - conftest.py
 - test_client_tgbot_unit.py
假设我们的app/client_tgbot.py包含一些逻辑,例如ClientTgBot和要测试的方法:

# app/client_tgbot.py
from aiohttp import ClientSession

class ClientTgBot:
    def __init__(self, token):
        self.token = token

    async def sendMessage(self, chat_id, text):
        """
        We want to test this method
        without sending POST request to the host https://api.telegram.org
        """
        url = "https://api.telegram.org/bot" + self.token + '/sendMessage'
        async with ClientSession() as c:
            response = await c.post(url, json={'chat_id': chat_id, 'text': text})
            return response
我们的固定装置:

# tests/conftest.py
import pytest
from aioresponses import aioresponses
from app.client_tgbot import ClientTgBot

@pytest.fixture
def mock_aioresponse():
    with aioresponses() as m:
        yield m

@pytest.fixture(scope="module")
def tg_token():
    TEST_FAKE_TOKEN = "12345:TEST_FAKE_TOKEN"
    yield TEST_FAKE_TOKEN

@pytest.fixture(scope="module")
def client_tgbot(tg_token):
    client = ClientTgBot(tg_token)
    yield client
我们的测试用例:

# tests/test_client_tgbot_unit.py
import pytest

@pytest.mark.asyncio
async def test_sendMessage(tg_token, client_tgbot, mock_aioresponse):
    JSON_RESPONSE_WRONG_MARKDOWN = {'ok': False, 'error_code': 400, 'description': "Bad Request: can't parse entities: Can't find end of the entity starting at byte offset 3"}
    mock_aioresponse.post(f"https://api.telegram.org/bot{tg_token}/sendMessage", payload=JSON_RESPONSE_WRONG_MARKDOWN)

    response = await client_tgbot.sendMessage(435627225, "bot_sent")

    assert response.status == 400
    assert await response.json() == JSON_RESPONSE_WRONG_MARKDOWN
安装一些libs:

pip3 install aiohttp aioresponses pytest pytest-asyncio
并运行您的测试:

python3 -m pytest -s . -vv
如你所见,我们已经模仿了整个urlhttps://api.telegram.org/bot12345:TEST_FAKE_TOKEN/sendMessage 不向真实主机发送POST请求。此外,我们没有任何假会议