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

如何用requests_mock模拟请求先超时数次再成功(pytest环境)

用requests_mock模拟先超时后成功的响应(适配Tenacity重试测试)

要实现先抛出几次requests.exceptions.ReadTimeout再返回成功的效果,你可以直接在response_list参数中混合配置异常和正常响应——每个列表元素既可以是定义异常的字典,也可以是定义正常响应的字典,requests_mock会按顺序逐个匹配每次请求。

完整代码示例

import pytest
import requests
from requests.exceptions import ReadTimeout
from tenacity import retry, stop_after_attempt, retry_if_exception_type
import requests_mock

# 定义带重试逻辑的被测试函数
@retry(
    stop=stop_after_attempt(2),  # 最多重试2次,总共尝试3次
    retry=retry_if_exception_type(ReadTimeout)
)
def fetch_data(url):
    response = requests.get(url)
    response.raise_for_status()
    return response.text

def test_retry_on_timeout_then_success():
    with requests_mock.Mocker() as m:
        # 配置:前2次请求抛ReadTimeout,第3次返回成功响应
        m.get(
            "https://example.com/api",
            response_list=[
                {"exc": ReadTimeout},
                {"exc": ReadTimeout},
                {"text": "Data loaded successfully", "status_code": 200}
            ]
        )
        
        # 调用被测试函数
        result = fetch_data("https://example.com/api")
        
        # 断言结果正确
        assert result == "Data loaded successfully"
        # 断言请求被调用了3次(2次失败重试 + 1次成功)
        assert m.call_count == 3

关键细节说明

  • response_list中的每个元素对应一次请求的处理逻辑:前两个元素通过exc键指定抛出ReadTimeout异常,最后一个元素配置正常的响应内容和状态码。
  • 被测试函数的重试次数(stop_after_attempt(2))要和mock的异常次数对应,确保最后一次请求能命中成功响应。
  • 可以通过m.call_count验证请求次数,确认重试逻辑确实触发了预期的次数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 04:12:04