使用requests Mock测试fetch_options时无法获取JSON响应的问题
问题分析与修复方案
1. Mock响应对象的错误
原函数试图直接将requests响应对象转成列表list(response),但实际requests的Response对象需要调用.json()方法才能获取返回的JSON数据。你的测试中给mock_response设置了json_data属性,但函数并未读取该属性,而是错误地尝试转换整个响应对象。
修复测试中的mock:
mock_response = MagicMock() mock_response.status_code = 200 # 模拟json()方法返回数据,而非设置json_data属性 mock_response.json.return_value = [{"id": "357", "strIngredient": "Orange"}, {"id": "358", "strIngredient": "Apple"}] mock_requests.get.return_value = mock_response
同时修改原函数获取数据的逻辑:
response_data = response.json() # 调用json()方法获取API返回的JSON数据 return render(request, "模板路径.html", {"meal": meal, "options": response_data[index]})
2. 索引越界的直接原因
当测试用例中field为"ingredients"时,index被设为1,但你mock返回的列表仅包含1个元素(索引仅为0),取索引1必然触发越界错误。需确保mock返回的列表长度至少为2,或根据实际API返回的数据结构调整索引逻辑。
3. render函数调用错误
Django的render函数签名为render(request, template_name, context=None, ...),你当前把上下文字典作为第二个参数传入,这会被当作模板名称,导致逻辑错误且无法返回正确的HttpResponse对象。必须传入合法的模板路径作为第二个参数,上下文作为第三个参数。
4. 测试中assertContains的使用问题
assertContains的第一个参数必须是Django的HttpResponse对象,但你当前传入的"request"是字符串,并非合法的HttpRequest对象,且原函数错误的render调用也无法返回正确响应。测试中需传入模拟的请求对象:
from django.http import HttpRequest @patch("planner.views.meals.requests") def test_fetch_options(self, mock_requests): # 创建模拟HttpRequest对象 request = HttpRequest() mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = [{"id": "357", "strIngredient": "Orange"}, {"id": "358", "strIngredient": "Apple"}] mock_requests.get.return_value = mock_response response = fetch_options(request, "breakfast", "ingredients") self.assertEqual(response.status_code, 200) # 可进一步验证上下文内容 self.assertEqual(response.context_data["options"], {"id": "358", "strIngredient": "Apple"})
5. 异常处理的错误
原函数中requests.raise_from_exception()是不存在的方法,正确的异常处理方式是直接重新抛出异常:
except ConnectionError as e: raise e # 或根据业务需求自定义异常处理逻辑
内容的提问来源于stack exchange,提问作者wavesinaroom
相关产品推荐
相关产品推荐

