Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an actual return value for a mocked file.read()

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?

like image 798
Brian Hicks Avatar asked Jan 05 '12 17:01

Brian Hicks


People also ask

What does @patch do in Python?

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.

How do I open a mock file in Python?

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

What is MagicMock?

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.

What is mock test in Python?

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.


1 Answers

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

like image 189
tbc0 Avatar answered Oct 08 '22 17:10

tbc0