如何使用requests-mock校验GET请求的查询参数?
问题
我有一个发送带参GET请求的函数,在单元测试中需确保参数设置正确。但使用requests-mock模拟请求时,仅能校验不含参数的URL,参数似乎未被requests-mock识别。
示例代码:
import requests as req def make_request(): url = "mock://some.url/media" headers = {"Authorization": "Bearer ..."} params = {"since": 0, "until": 1} req.get(url, params=params, headers=headers, timeout=30)
示例测试:
import requests_mock def my_test(): auth_headers = {"Authorization": "Bearer ..."} query_params = "?since=0&until=1" expected_url = f"mock://some.url/media{query_params}" # 触发No Mock Address错误 with requests_mock.Mocker() as mocker: mocker.get( expected_url, headers=auth_headers, text="media_found", ) response = make_request() assert response.text == "media_found" # assert mocker.last_request.params == query_params
按此方式测试时,只要expected_url包含query_params就会出现No Mock Address错误。若使用不含参数的URL,测试可正常运行,但无法校验查询参数是否正确设置。我查阅文档尝试了query-string-matcher,但仍出现相同错误。调试request_history对象时,未找到params/query字段:
_url_parts: ParseResult(scheme='mock', netloc='some.url', path='/media', params='', query='', fragment='') _url_parts_: ParseResult(scheme='mock', netloc='some.url', path='/media', params='', query='', fragment='')
这令人意外,因为在测试外发送实际请求时参数会被正确添加。
请问如何在不创建req.get()函数spy、不检查函数调用参数的前提下,使用requests-mock校验GET请求的查询参数?
解决方案
方法1:使用requests-mock的查询参数匹配器
直接在mock时指定query参数匹配请求的查询字符串,无需将参数拼入URL:
import requests_mock def my_test(): auth_headers = {"Authorization": "Bearer ..."} expected_params = {"since": "0", "until": "1"} # 注意参数值会被转为字符串 with requests_mock.Mocker() as mocker: # 仅匹配基础URL,通过query参数校验请求参数 mocker.get( "mock://some.url/media", headers=auth_headers, text="media_found", query=expected_params ) response = make_request() assert response.text == "media_found"
只有当请求的查询参数完全匹配expected_params时,mock才会生效,自动完成参数校验。
方法2:校验last_request的查询参数
若需要灵活校验(比如部分参数匹配),可在请求发送后解析mocker.last_request的查询参数做断言:
import requests_mock from urllib.parse import parse_qs def my_test(): auth_headers = {"Authorization": "Bearer ..."} with requests_mock.Mocker() as mocker: # 先mock基础URL,不限制参数 mocker.get( "mock://some.url/media", headers=auth_headers, text="media_found", ) response = make_request() assert response.text == "media_found" # 解析实际请求的查询参数 actual_params = parse_qs(mocker.last_request.query) # parse_qs返回值为列表,需取[0]获取单个参数值 assert actual_params["since"][0] == "0" assert actual_params["until"][0] == "1"
注意事项
- 调试时
_url_parts的query字段为空是正常现象:requests-mock会将查询参数从URL中剥离单独处理,但last_request.query会保留实际的查询字符串。 - 使用
query匹配器时,参数值需与实际请求一致(比如整数参数会被转为字符串,需写"0"而非0)。
内容的提问来源于stack exchange,提问作者Philip Koch
相关产品推荐
相关产品推荐

