Python – Pytest: Mock/monkey tinkering The built-in input() and print() functions in python

Pytest: Mock/monkey tinkering The built-in input() and print() functions in python… here is a solution to the problem.

Pytest: Mock/monkey tinkering The built-in input() and print() functions in python

How can I use Pytest monkey to patch the built-in input and print functions so that the output of other people’s code is captured and refactored with pytest before?

For example, I got some code like this:

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())

I don’t want

to read dozens of input parameters from stdin, and I don’t want to print out. I want to filter a directory full of mytest.in and mytest.out files using the function I wrote and pass input to pytest using @pytest.mark.parametrize(...).

But I don’t know how to patch the clunky read… and write... functions in this class.

I suspect so:

@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 ...

Can you help?

Thank you very much

Solution

While waiting for a reply, I thought of the following myself. I think the ideal answer is what I implemented as suggested by @hoefling – using patches.

@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

Update:

@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

Related Problems and Solutions