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

如何在Pytest中Mock多次Socket Error异常以适配重试逻辑?

如何在Pytest中Mock多次Socket Error异常以适配重试逻辑

针对你的场景:父类parentjob新增了3次重试逻辑,原测试用例仅mock单次socket.error无法覆盖完整重试流程,这里提供两种可行的Mock方式:

方法一:使用异常列表匹配重试次数

直接通过requests-mock的exc参数传入异常列表,列表长度对应重试次数,让每次请求都抛出socket.error:

def test_socketerror(monkeypatch, requests_mock):
    monkeypatch.setenv('ENV_ID', 'Local')
    # 模拟3次socket.error,与重试次数对应
    requests_mock.post(
        "http://localhost:8080/samplejob",
        exc=[socket.error] * 3
    )

    with pytest.raises(CommunicationError) as ce:
        job_id = 'JOB_ID'
        executor = parentjob()
        executor.samplejob(job_id, None, None, None, None)
    assert str(ce.value.args[0]) == "error message on parent method"

逻辑说明

  • [socket.error] * 3会生成包含3个socket.error实例的列表,requests-mock会按顺序每次请求抛出一个异常。
  • 每次异常触发后,parentjob中的response保持为None,执行sleep后进入下一次循环;3次循环结束后,因response仍为None,最终抛出CommunicationError,与断言的错误信息匹配。

方法二:使用side_effect实现动态异常抛出

如果后续重试次数可能调整,用side_effect传入一个抛出异常的函数,每次请求都会触发该函数抛出socket.error,不需要固定列表长度:

def test_socketerror(monkeypatch, requests_mock):
    monkeypatch.setenv('ENV_ID', 'Local')
    
    def mock_socketerror():
        raise socket.error
    
    requests_mock.post(
        "http://localhost:8080/samplejob",
        side_effect=mock_socketerror
    )

    with pytest.raises(CommunicationError) as ce:
        job_id = 'JOB_ID'
        executor = parentjob()
        executor.samplejob(job_id, None, None, None, None)
    assert str(ce.value.args[0]) == "error message on parent method"

逻辑说明

  • side_effect绑定的函数会在每次请求时执行,每次都抛出socket.error,完美适配任意次数的重试逻辑。
  • 循环执行完所有重试次数后,parentjob会因response为None抛出CommunicationError,满足测试断言要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:15:25