如何使用requests_mock为同一API返回不同响应以测试循环调用?
如何用requests_mock为同一URL返回不同响应以终止循环测试
我正尝试在单元测试中使用requests_mock来测试带有while循环的API调用。为了终止while循环,需要让API返回不同的响应——URL保持不变但参数有变化,但requests_mock默认不区分参数。
待测试函数
def func(): response = requests.get( url=<url>, params={"limit": 1000}, headers=<headers> ).json() while "next" in response["info"].keys(): response = requests.get( url=<url>, params={"limit": 1000, "info": response["info"]}, headers=<headers> ).json()
原测试代码
def test_url(requests_mock): requests_mock.get(url, json=<response_with_info_key>) func() data_request = requests_mock.request_history[0] assert data_request.query == "limit=1000"
尝试过的无效方法
我曾尝试传入响应列表,但未达到预期效果:
def test_url(requests_mock): requests_mock.get(url, json=[<response_with_info_key>, <response_without_info_key>]) func() data_request = requests_mock.request_history[0] assert data_request.query == "limit=1000"
核心问题:如何让requests_mock为同一API发送两个不同的响应?
解决方案
方法1:使用side_effect参数返回序列响应
requests_mock的get方法支持side_effect参数,传入响应列表后,每次请求会依次返回列表中的内容,刚好匹配循环的两次请求场景。
修改后的测试代码:
def test_url(requests_mock): # 定义两个响应:第一个带"next"触发循环,第二个不带终止循环 response_with_next = {"info": {"next": "sample_token"}} response_without_next = {"info": {}} # 通过side_effect按顺序返回响应 requests_mock.get(url, side_effect=[response_with_next, response_without_next]) func() # 验证两次请求的参数 first_request = requests_mock.request_history[0] assert first_request.query == "limit=1000" second_request = requests_mock.request_history[1] assert "limit=1000" in second_request.query assert "info=sample_token" in second_request.query
方法2:根据请求参数动态返回响应
如果需要更灵活的控制(比如根据请求参数的不同返回对应响应),可以给side_effect传入一个函数,通过解析请求参数来判断返回内容。
示例代码:
def test_url(requests_mock): def dynamic_response(request): # 解析请求的查询参数 params = request.qs if "info" not in params: # 第一次请求(无info参数),返回带next的响应 return {"info": {"next": "sample_token"}} else: # 第二次请求(含info参数),返回不带next的响应 return {"info": {}} requests_mock.get(url, json=dynamic_response) func() # 验证确实发起了两次请求 assert len(requests_mock.request_history) == 2
注意事项
- 待测试函数中
requests.get的参数缺少逗号(比如url=<url>后需要加逗号),需先修正语法错误才能正常运行。 - 使用
side_effect的列表模式时,要确保列表长度与预期请求次数匹配,超出次数会抛出StopIteration异常。 - 可通过
requests_mock.request_history查看所有请求记录,用于验证请求参数的正确性。
内容的提问来源于stack exchange,提问作者techdoodle
相关产品推荐
相关产品推荐

