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?
This, along with its subclasses, will meet most Python mocking needs that you will face in your tests. The library also provides a function, called patch() , which replaces the real objects in your code with Mock instances.
Basically, open() will return an object and with will call __enter__() on that object. To mock properly, we must mock open() to return a mock object. That mock object should then mock the __enter__() call on it ( MagicMock will do this for us) to return the mock data/file object we want (hence mm. __enter__.
MagicMock. MagicMock objects provide a simple mocking interface that allows you to set the return value or other behavior of the function or object creation call that you patched. This allows you to fully define the behavior of the call and avoid creating real objects, which can be onerous.
mock is a library for testing in Python. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used. unittest. mock provides a core Mock class removing the need to create a host of stubs throughout your test suite.
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With