Не удалось исправить метод класса сервера rpc

avatar
Antonio Santoro
1 июля 2021 в 16:12
69
1
0

Мне нужно отредактировать метод класса, украшенный аннотацией @method библиотеки jsonrpcserver. Класс реализует сервер rpc, который запускается как асинхронный сервер и запускается с помощью такого приспособления pytest

.
# conftest.py
@pytest.fixture(autouse=True, scope="module")
@pytest.mark.asyncio
async def rpc_server(...):

    rpc_server = RpcServer(
        addr="127.0.0.1",
        port=9500,
        ...
    )

    task = asyncio.create_task(rpc_server.start())
    yield rpc_server
    task.cancel()

Тест должен исправить один из методов класса RpcServer

# test_rpc.py
@pytest.mark.asyncio
async def test_rpc_server_exception(
    rpc_server: RpcServer,
    ...
    monkeypatch: MonkeyPatch,
):
    async def raise_runtime_error():
        raise RuntimeError()

    monkeypatch.setattr(
        RpcServer, "method_to_be_patched", raise_runtime_error, raising=True
    )

    ... # making an rpc request to launch method_to_be_patched

    assert ...

method_to_be_patched вызывается async_dispatch библиотеки jsonrpcserver после получения нового запроса и выглядит следующим образом

# rpc_server.py
@method
async def method_to_be_patched(self, ...) -> str:
    ...
    return ...

Проблема в том, что monkeypatch ничего не исправляет, и тест проходит без каких-либо исключений (как мне и нужно). Я безуспешно пытался выполнить команду monkeypatch RpcServer и выход экземпляра из приспособления pytest, но при отладке кажется, что метод класса правильно указывает на фиктивную функцию, но все же вызывается исходная функция.

РЕДАКТИРОВАТЬ: проблема возникает из-за работы импорта python. Насколько я понял, при импорте типа from ... import ... я создаю новую ссылку, поэтому в основном я исправляю ссылку, созданную из test_rpc.py, а не ссылку в rpc_server.py (поправьте меня, если я ошибаюсь).

Я попытался

# test_rpc.py
@pytest.mark.asyncio
async def test_rpc_server_exception(
    rpc_server: RpcServer,
    ...
    monkeypatch: MonkeyPatch,
):
    async def raise_runtime_error():
        raise RuntimeError()
    import network # the package containing rpc_server.py
    monkeypatch.setattr(
        network.rpc_server.RpcServer, "method_to_be_patched", raise_runtime_error, raising=True
    )

    ... # making an rpc request to launch method_to_be_patched

    assert ...

но по-прежнему не достигается ожидаемое поведение.

Дерево проекта выглядит следующим образом

/src
    |rpc_server.py
/test
    |conftest.py
    /e2e
        |test_rpc.py
Источник

Ответы (1)

avatar
Antonio Santoro
1 июля 2021 в 17:59
0

Решение заключается в monkeypatch where вызывается метод, поэтому, поскольку я использую здесь jsonrpcserver, мне пришлось обезвреживать метод call, определенный внутри модуля async_dispatch, и теперь он работает как я и ожидал