【问题标题】:Unable to monkeypatch an rpc server class method无法对 rpc 服务器类方法进行monkeypatch
【发布时间】:2021-07-01 16:12:00
【问题描述】:

我需要对一个用jsonrpcserver 库的@method 注释修饰的类方法进行monkeypatch。该类正在实现一个 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类的方法之一进行monkeypatch

# 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 ...

一旦收到新请求,jsonrpcserver 库的async_dispatch 就会调用method_to_be_patched,看起来像这样

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

问题是monkeypatch 没有修补任何东西并且测试通过而没有引发任何异常(就像我需要的那样)。我已经尝试从 pytest 固定装置进行monkeypatch RpcServer 和实例产量但没有任何成功,但通过调试似乎类方法正确指向了虚拟函数,但仍然调用了原始函数。

编辑:问题是由于 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

【问题讨论】:

    标签: python pytest rpc monkeypatching json-rpc


    【解决方案1】:

    解决方案是对调用方法的 where 进行monkeypatch,因此由于我在这里使用jsonrpcserver,因此我必须对async_dispatch 模块中定义的call 方法进行monkeypatch,现在它是按我的预期工作

    【讨论】:

      猜你喜欢
      • 2020-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 2014-11-08
      • 2021-03-26
      • 1970-01-01
      相关资源
      最近更新 更多