Как использовать PropertyMock для возврата атрибутов ответа на запросы в модульном тесте pytest?

Я использую оболочку pytest-mock с pytest.

Я не могу заставить PropertyMock работать с пакетом запросов.

Вот пример функции, которую я пытаюсь выполнить модульным тестом:

def get():
    url = f'http://foo.bar/'
    response = requests.get(url)
    if response.status_code != 200:
        sys.exit(1)
    return response.text

И вот моя попытка юнит-теста:

import pytest
import my_module
import requests

def test_get(mocker, monkeypatch):
    response_mock = mocker.MagicMock()
    status_code_mock = mocker.PropertyMock(return_value=200)
    text_mock = mocker.PropertyMock(return_value='xyz')
    type(response_mock).status_code = status_code_mock
    type(response_mock).text = text_mock
    monkeypatch.setattr(requests, 'get', response_mock)

    my_module.get()

Тест не пройден, потому что 200 не возвращается response.status_code,

Я пытался поставить точку останова PDB после requests.get() позвонить и сам проверил атрибут response.status_code в PDB. Я получаю объект MagicMock:

(Pdb) response.status_code
<MagicMock name='mock().status_code' id='4487925656'>

1 ответ

Решение

Это возвращаемое значение requests.get вызов, который назначен response переменная.

В этой строке:

monkeypatch.setattr(requests, 'get', response_mock)

Вы заменили сам метод get на макет. Но то, что вы, вероятно, хотели, это заменить его чем-то, что возвращает ваш ответ, например, при вызове:

monkeypatch.setattr(requests, 'get', lambda url: response_mock)

Кроме того, рассмотрите использование существующих плагинов / приспособлений pytest для этого кода. requests_mock а также responses оба хороших выбора. После pip install requests_mock Например, ваш тест может выглядеть следующим образом:

def test_get_better(requests_mock):
    requests_mock.get("http://foo.bar/", text="xyz")
    response_text = my_module.get()
    assert response_text == "xyz"
Другие вопросы по тегам