Макет ответа api

#python #pytest

#python #pytest

Вопрос:

Предыстория

У меня есть функция под названием submit_health, которая отвечает за выполнение запроса POST для некоторых передаваемых нами данных. Ожидаемый результат всегда имеет следующую форму :

 {
    "errors": [],
    "warnings": [],
    "success": true
} 
  

Единственное отличие заключается в том, что в некоторых случаях, если мы отправляем неверные данные, "success": false возможно, и, конечно, «ошибки» и «предупреждения» будут содержать соответствующий текст, указывающий, почему не было успешного запроса post.

Код

    def submit_health(health_data):
        return _post_json("health-single", health_data)


def _post_json(resource: str, data: Dict) -> PostResponse:
    json_data = json.dumps(data, default=json_encoding_decimal_default)
    response = request_session_with_retry().post(
        f"{SITE_API_ROOT}/v3/{resource}",
        auth=("", SITE_API_V3_KEY),
        data=json_data,
        headers={"Content-Type": "application/json", "User-Agent": USER_AGENT},
    )
    response.raise_for_status()
    try:
        return json.loads(response.text)
    except Exception:
        return None
  

ПРОБЛЕМА

Я пытаюсь протестировать submit_health функцию с помощью pytest. Меня не интересует реализация API, поскольку с этим тестом имеет дело другая часть кода. Меня интересует только его тестирование с ожидаемым результатом, который

 {
    "errors": [],
    "warnings": [],
    "success": true
} 
  

Мой вопрос в том, как бы я издевался над этим ответом? Я был бы рад любым предложениям. Я немного читал об исправлении monkey, но я пока не совсем уверен, как имитировать ответ. Я был бы рад получить некоторые рекомендации.

Ответ №1:

Предполагая, что ваша функция расположена в health.py модуле, я бы создал test_health.py модуль с кодом:

 from unittest.mock import Mock, patch

from health import submit_health


@patch("health.request_session_with_retry")
def test_submit_health(request_mock):
    response_mock = Mock(text='{"errors": [], "warnings": [], "success": true}')
    request_mock.return_value.get.return_value = response_mock

    result = submit_health({"foo": "bar"})

    assert result == {"errors": [], "warnings": [], "success": True}
  
  1. @patch передает исправленную функцию в качестве аргумента, который я назвал request_mock
  2. Нам нужно указать, что этот макет будет возвращать при request_session_with_retry.get вызове

Комментарии:

1. @bigbounty есть ли причина, по которой вы рекомендуете контекстныеменеджеры?