如何用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
相关产品推荐
相关产品推荐

