You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pytest中构造带自定义状态码和信息的grpc.RpcError

在pytest中构造自定义状态码和详情的grpc.RpcError

grpc.RpcError是抽象基类,无法直接实例化,你可以通过以下两种方式构造符合需求的异常,用于Mock场景:

方法一:模拟真实的grpc异常实例

grpc实际抛出的RpcError子类是grpc._channel._InactiveRpcError,你可以通过构造该类并传入mock的Call对象来生成自定义异常:

from unittest.mock import Mock
import grpc

def build_custom_rpc_error(status_code: grpc.StatusCode, error_details: str):
    # 构造mock的Call对象,实现code()和details()方法
    mock_call = Mock()
    mock_call.code.return_value = status_code
    mock_call.details.return_value = error_details
    # 创建_InactiveRpcError实例
    return grpc._channel._InactiveRpcError(mock_call)

在测试中使用:

def test_grpc_error_logging(mocker):
    # 打桩你的grpc调用方法,让它抛出自定义异常
    mocker.patch(
        "your_project.your_module.grpc_call_method",
        side_effect=build_custom_rpc_error(grpc.StatusCode.NOT_FOUND, "请求的资源不存在")
    )
    # 执行被测逻辑
    your_project.your_module.your_function_under_test()
    # 这里可以通过捕获日志或输出,验证状态码和详情是否符合预期格式

方法二:直接Mock RpcError对象(轻量方案)

如果你仅关注code和details属性的取值,不需要完整的grpc异常行为,直接用Mock模拟即可:

from unittest.mock import Mock
import grpc

def test_mocked_rpc_error_output(mocker):
    # 创建符合RpcError接口的mock对象
    mock_rpc_err = Mock(spec=grpc.RpcError)
    mock_rpc_err.code.return_value = grpc.StatusCode.PERMISSION_DENIED
    mock_rpc_err.details.return_value = "当前用户无操作权限"
    
    # 打桩目标方法抛出该mock异常
    mocker.patch(
        "your_project.your_module.grpc_call_method",
        side_effect=mock_rpc_err
    )
    
    # 执行被测代码,验证打印的异常信息格式
    your_project.your_module.your_function_under_test()

注意事项

  • 方法一中的_InactiveRpcError是grpc的私有类,不同版本可能有变动,但测试场景下通常可以稳定使用;
  • 方法二更轻量,且不依赖grpc内部实现,适合仅验证属性取值的场景(比如你的需求:仅关注打印的状态码和详情格式)。

内容的提问来源于stack exchange,提问作者garandizier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 18:24:25