1

I am trying to mock.patch sys.stdout to StringIO as a decorator to record the output for testing.

As a 'with' statement it works this way:

with mock.patch('sys.stdout', new_callable = StringIO) as recorded_output:
 print('OUTPUT')
 r = recorded_output.getvalue()
print(r)

gets 'OUTPUT', but 'getvalue' doesn't work when used as a decorator:

@mock.patch('sys.stdout', new_callable = StringIO)
def test_stdout(self, recorded_output):
 print('OUTPUT')
 r = recorded_output.getvalue()
 print(r)

gets error: Mock object has no attribute 'getvalue'

Does anyone know how to write this as a decorator?

asked Sep 12 at 10:36
2
  • 2
    Pytest provides a set of fixtures to capture stdout already; can you use one of these for your test? Commented Sep 12 at 11:13
  • 1
    I don't know why you get this error (I don't when I try it), but your last print won't work anyway since stdout is still mocked at this point. Commented Sep 12 at 12:16

1 Answer 1

0

There is an example in mock documentation that does exactly what you want (and I bet you already read it according to your code :-))

The example is pretty much like this

from io import StringIO
from unittest.mock import patch
def foo():
 print('Something')
@patch('sys.stdout', new_callable=StringIO)
def test(mock_stdout):
 foo()
 assert mock_stdout.getvalue() == 'Something\n'
test()

But, you are trying to use the print function inside the mock, and it is not a directly call to the sys.stdout. A good way to handle with this issue is to add a mock for the print function as the following example.

from io import StringIO
from unittest.mock import patch, call
@patch('builtins.print')
def test_print(mocked_print):
 print('Something')
 print()
 assert mocked_print.mock_calls == [call('Something'), call()]

But if you want to mix the both approaches, then David Maze proposal's certainly is the better way to handle with it.

answered Sep 22 at 10:28
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.