如何为带重试与超时的Python requests请求函数编写单元测试
为HTTP请求函数编写单元测试的方案
原函数代码(修正语法错误后)
from requests import Session from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry def http_request(method, url): session = Session() retries = Retry(total=3, backoff_factor=0.5, status_forcelist=list(range(500, 600))) for prefix in ('http://', 'https://'): session.mount(prefix, HTTPAdapter(max_retries=retries)) response = session.request(method, url, timeout=(31,123)) response.raise_for_status() return response
测试需求验证方案
1. 验证500-600状态码触发3次重试(总计4次调用)
使用requests-mock模拟服务器返回500错误,通过统计mock的调用次数确认重试逻辑生效。
测试代码(基于pytest):
import pytest import requests_mock from your_module import http_request # 替换为实际的模块名 def test_http_request_retries_on_server_errors(): with requests_mock.Mocker() as m: # 模拟目标URL返回500状态码 m.register_uri('GET', 'http://example.com', status_code=500) with pytest.raises(requests.exceptions.HTTPError): # 调用目标函数,预期最终重试失败后抛出HTTPError http_request('GET', 'http://example.com') # 验证总调用次数为4次(1次初始请求 + 3次重试) assert m.call_count == 4
2. 验证超时设置被正确传递
通过unittest.mock补丁requests.Session.request方法,检查调用时是否传入了正确的超时参数。
测试代码(基于pytest):
from unittest.mock import patch, MagicMock from your_module import http_request # 替换为实际的模块名 def test_http_request_timeout_setting(): with patch('requests.Session.request') as mock_request: # 模拟响应成功,避免抛出异常 mock_response = MagicMock() mock_response.raise_for_status.return_value = None mock_request.return_value = mock_response # 调用目标函数 http_request('GET', 'http://example.com') # 验证request方法被调用时,timeout参数正确设置为(31, 123) mock_request.assert_called_once_with( 'GET', 'http://example.com', timeout=(31, 123) )
依赖说明
运行测试前需要安装依赖:
pip install pytest requests-mock
内容的提问来源于stack exchange,提问作者iAmoric
相关产品推荐
相关产品推荐

