Pytest: встроенные функции ввода () и печати () в Python - PullRequest
0 голосов
/ 09 мая 2018

Как можно с помощью Pytest обезьянить пропатчить встроенные функции input и print, чтобы захватить вывод чужого кода и проверить его с помощью pytest перед рефакторингом?

Например, я получил код, подобный следующему:

class QueryProcessor:
    def __init__(self ...):
        ...  

    def write_search_result(self, was_found):
        print('yes' if was_found else 'no')

    def read_query(self):
        return Query(input().split())

Я не хочу читать десятки входных параметров из stdin и не хочуprint выходы.Я хочу использовать написанные мной функции, которые просеивают каталог, полный файлов mytest.in и mytest.out, и передают входные данные в pytest, используя @pytest.mark.parametrize(...).

Но я не могу понять, как исправить неловкие функции read… и write… в этом классе.

Я подозреваю, что это что-то вроде:

@yptest.mark.parametrize("inputs…, expected outputs…", data_reading_func())
def test_QueryProcessor(monkeypatch, inputs…, expected outputs…):
   """Docstring
   """
   q = QueryProcessor()

   def my_replacement_read():
       ...
       return [...]

   def my_replacement_write():
       ...
       return [...]

   monkeypatch.???
   assert ...

Вы можете помочь?

Большое спасибо

1 Ответ

0 голосов
/ 09 мая 2018

В ожидании ответа я сам придумал следующее.Я думаю, что идеальным ответом будет то, что я сделал, реализованный так, как предлагает @hoefling - используя patch.

@pytest.mark.parametrize("m, n, commands, expec", helpers.get_external_inputs_outputs('spampath', helpers.read_spam_input_output))
def test_QueryProcessor(monkeypatch, m, n, commands, expec):

    def mock_process_queries(cls):
        for cmd in commands:
            cls.process_query(Query(cmd.split())) # also mocks read_query()

    def mock_write_search_result(cls, was_found):
        outputs.append('yes' if was_found else 'no')

    monkeypatch.setattr('test.QueryProcessor.process_queries', mock_process_queries)
    monkeypatch.setattr('test.QueryProcessor.write_search_result', mock_write_search_result)

    outputs = []

    proc = QueryProcessor(m)
    proc.process_queries()

    assert outputs == expec

ОБНОВЛЕНИЕ:

@pytest.mark.parametrize("m, n, commands, expec",
                         helpers.get_external_inputs_outputs(
                             'spampath',
                             helpers.read_input_output))
def test_QueryProcessor_mockpatch(m, n, commands, expec):

    commands.insert(0,n)

    mock_stdout = io.StringIO()

    with patch('spammodule.input', side_effect=commands):
        with patch('sys.stdout', mock_stdout):
            proc = hash_chains.QueryProcessor(m)
            proc.process_queries()

    assert mock_stdout.getvalue().split('\n')[:-1] == expec
...