I\'ve tried
from mock import Mock
import __builtin__
__builtin__.print = Mock()
But that raises a syntax error. I\'ve also tried patching
First, the module is called __builtins__
and you don't need to import it.
Now, in Python 2 print
is a keyword so you can't use it as an attribute name directly. You can use setattr
/getattr
to workaround it:
getattr(__builtins__, "print")
Another option is to use from __future__ import print_function
which changes how Python parses the module to Python 3 syntax.
As lcq says, print is a keyword. So, think about what it would mean if you were actually successful in patching/mocking print under Python 2.7.3. You would have code like this:
print "Hi."
turning into:
<MagicMock id='49489360'> "Hi."
MagicMock objects cannot be accessed this way, so you would get a syntax error.
So... Yeah. You can only mock the Python3 print function or sys.stdout.
print
is a keyword in python 2.x, using it as attribute raises a SyntaxError. You can avoid that by using from __future__ import print_function
in the beginning of the file.
Note: you can't simply use setattr
, because the print function you modified doesn't get invoked unless the print
statement is disabled.
Edit: you also need to from __future__ import print_function
in every file you want your modified print
function to be used, or it will be masked by the print
statement.
import mock
import sys
mock_stdout = mock.Mock()
sys.stdout = mock_stdout
print 'Hello!'
sys.stdout = sys.__stdout__
print mock_stdout.mock_calls
[call.write('Hello!'), call.write('\n')]
This Python 3 example builds upon the Python 2 answer by Krzysztof. It uses unittest.mock
. It uses a reusable helper method for making the assertion.
import io
import unittest
import unittest.mock
from .solution import fizzbuzz
class TestFizzBuzz(unittest.TestCase):
@unittest.mock.patch('sys.stdout', new_callable=io.StringIO)
def assert_stdout(self, n, expected_output, mock_stdout):
fizzbuzz(n)
self.assertEqual(mock_stdout.getvalue(), expected_output)
def test_only_numbers(self):
self.assert_stdout(2, '1\n2\n')