无法在请求模拟中发送json响应

问题描述 投票:0回答:1

我正在寻找一种方法来测试名为

fetch_options
的函数,该函数基本上呈现从内部 API 返回的 JSONResponse。我的测试方法是模拟
requests
,因为内部 API 位于另一个应用程序中,该应用程序已经在不同的测试套件中进行了测试。

我有一种直觉,该函数已通过模拟正确修补,但由于某种原因,我的

render
调用无法获取响应数据,但我对此可能是错的。

planner/views/meals.py

def fetch_options(request, meal, field):
    if field == "ingredients":
        index = 1
    else:
        index = 0

    try:
        response = requests.get("log/api/send_" + field) #Trying to mock requests here, request fetches from /log/views/api.py
    except ConnectionError:
        requests.raise_from_exception()
    else:
        return render(request, {"meal": meal, "options": list(response)[index]}) # throws list index out range in tests

/log/views/api.py

def send_data(request, option):
    match option:
        case "ingredients":
            data = Log.objects.first().recipe_ingredients
        case "areas":
            data = Log.objects.first().recipe_area
        case "categories":
            data = Log.objects.first().recipe_categories
        case "activities":
            data = Log.objects.first().activities
    response = JsonResponse(data, status=200, safe=False)
    return response

计划者/测试/test_meals_view.py

from unittest import MagicMock, patch

@patch("planner.views.meals.requests")
def test_fetch_options(self, mock_requests):
    mock_response = MagicMock()
    mock_response.status_code = 200
    mock_response.json_data = [{"id": "357", "strIngredient": "Orange"}]
    mock_requests.get.return_value = mock_response
    self.assertContains(
        fetch_options("request", "breakfast", "ingredients"), status_code=200
    )

谁能告诉我我错过了什么或做错了什么?

python django python-requests mocking
1个回答
0
投票

1. 您正在创建一个

list
,其中包含一个元素 — response [requests-docs],位于
list(response)
。如果
field
==
"ingredients"
index
==
1。现在看到错误了吗?当索引包含索引
1
处的一个元素的 list 时,会引发
IndexError
异常。

2. 辅助函数

render()
[django-docs] 不采用您使用的函数签名:

render(request, {"meal": meal, "options": list(response)[index]})

正确的签名是:

render(request, template_name, •••Rest of parameters•••)

我的建议是:

1. 首先读取

Response
中的
requests.get()
,并将数据提取为
JSON
Text

response.json()
# OR
response.text

2. 考虑直接构造并返回 Django

HttpResponse
,而不是使用
render()
,后者将对
Context
数据进行一些 HTML 渲染。我建议这样做是因为我意识到您不需要 HTML 渲染,因为您要检查的只是
status_code
in:

self.assertContains(
    fetch_options("request", "breakfast", "ingredients"), status_code=200
)
© www.soinside.com 2019 - 2024. All rights reserved.