I'm using python-mock to mock out a file open call. I would like to be able to pass in fake data this way, so I can verify that read()
is being called as well as using test data without hitting the filesystem on tests.
Here's what I've got so far:
file_mock = MagicMock(spec=file)
file_mock.read.return_value = 'test'
with patch('__builtin__.open', create=True) as mock_open:
mock_open.return_value = file_mock
with open('x') as f:
print f.read()
The output of this is <mock.Mock object at 0x8f4aaec>
intead of 'test'
as I would assume. What am I doing wrong in constructing this mock?
Edit:
Looks like this:
with open('x') as f:
f.read()
and this:
f = open('x')
f.read()
are different objects. Using the mock as a context manager makes it return a new Mock
, whereas calling it directly returns whatever I've defined in mock_open.return_value
. Any ideas?
In Python 3 the pattern is simply:
>>> import unittest.mock as um
>>> with um.patch('builtins.open', um.mock_open(read_data='test')):
... with open('/dev/null') as f:
... print(f.read())
...
test
>>>
(Yes, you can even mock /dev/null to return file contents.)