Изменение второго результата вызова функции с помощью макета

У меня есть цикл, который выглядит так:

for i in range(len(some_list)):
    response = requests.post(some_url, some_params)
    if response.status_code != HTTPOk:
       # do something

Что я хотел бы сделать, так это изменить ответ request.post во второй итерации цикла. Из своего теста я знаю, что могу сделать что-то вроде:

mock_response = mock.Mock()
mock_response.status_code = 404
with mock.patch(mymodule.requests.post, return_value=mock_response):
   mymodule.some_function()

Но это, кажется, работает только для одного status_code. Я посмотрел на side_effect, и он выглядит так: Я могу перебирать цикл так:

mock_response.side_effect = [
    mock.Mock(status_code=400), mock.Mock(status_code=200)
]
with mock.patch(mymodule.requests.post, return_value=mock_response):
   mymodule.some_function()

Однако похоже, что на самом деле он не получает «правильный» код состояния. Каков наилучший способ изменить поведение в side_effect или return_value, чтобы правильно получить желаемое поведение? Я думаю, что мне нужен side_effect, но я не уверен, как лучше всего издеваться над ответами.


person TJ1S    schedule 28.04.2015    source источник


Ответы (2)


Более простой и чистый способ сделать это

with mock.patch("mymodule.requests.post", 
                side_effect=[Mock(status_code=400), Mock(status_code=200)]) as mock_post:
   mymodule.some_function()

patch создайте mock_post объект на MagicMock(side_effect=mock_responses) и замените mymodule.requests.post ссылкой. Вы также можете использовать mock_post для проверки вызовов post(), например:

mock_post.assert_has_calls([mock.call(first_url, first_params), mock.call(second_url, second_params)])

Вы можете выполнить ту же работу, создав и настроив mock_post раньше, а затем передать его как параметр new (второй аргумент patch), но таким образом у вас есть 2 недостатка.

  1. Больше кода для написания
  2. Потерять возможность использовать autospec=True параметры в patch

Autospeccing – очень мощная функция mock framework, которая предотвращает многие глупой ошибки как в тесте, так и в коде.

person Michele d'Amico    schedule 28.04.2015

На самом деле оказалось, что это было так просто:

mock_response.side_effect = [
    mock.Mock(status_code=400), mock.Mock(status_code=200)
]
with mock.patch(mymodule.requests.post, mock_response):
   mymodule.some_function()
person TJ1S    schedule 28.04.2015