Как использовать pytest capsys на тестах, которые имеют декораторы-насмешки? - PullRequest
0 голосов
/ 28 августа 2018

Я пытался найти способ использовать насмешливые декораторы и pytest capsys одновременно, но я не смог найти правильный способ сделать это.

import pytest
import requests_mock


@requests_mock.mock()
def test_with_mock(m):
    pass

def test_with_capsys(capsys):
    pass


# how to write a test that works with both?

1 Ответ

0 голосов
/ 28 августа 2018

Как указано в документах 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 уже предлагает прибор, зачем использовать декоратор?

...