Как указано в документах request-mock
:
pytest
имеет свой собственный метод регистрации и загрузки пользовательских приборов. requests-mock
предоставляет внешний прибор, зарегистрированный в pytest
, так что его можно использовать, просто указав его в качестве параметра. Нет необходимости импортировать requests-mock
, его просто нужно установить и указать аргумент requests_mock
.
Устройство затем предоставляет тот же интерфейс, что и requests_mock.Mocker
, позволяя вам использовать requests-mock
, как и следовало ожидать.
>>> import pytest
>>> import requests
>>> def test_url(requests_mock):
... requests_mock.get('http://test.com', text='data')
... assert 'data' == requests.get('http://test.com').text
...
Так что просто используйте приспособление requests_mock
вместо декоратора:
def test_with_mock_and_capsys(requests_mock, capsys):
pass
Фон
pytest
не подходит для декораторов функций, которые добавляют позиционные аргументы в тестовую функцию. pytest
считает все аргументы, которые
- не привязаны к экземпляру или типу как методы экземпляра или класса;
- не имеет значений по умолчанию;
- не связаны с
functools.partial
;
- не заменяются на
unittest.mock
mocks
будет заменено значениями приборов и завершится ошибкой, если не найдет подходящего прибора для какого-либо аргумента. Так что вроде
import functools
import pytest
def deco(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
args += ('spam',)
return func(*args, **kwargs)
return wrapper
@deco
def test_spam(spam_arg):
assert True
потерпит неудачу, и это именно то, что requests-mock
делает. Обходной путь к этому - передать насмешника через ключевое слово args:
import pytest
import requests_mock
@requests_mock.Mocker(kw='m')
def test_with_mock_and_fixtures(capsys, **kwargs):
m = kwargs['m']
...
но поскольку requests-mock
уже предлагает прибор, зачем использовать декоратор?