Search code examples
pythontddmockingpython-mock

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?


Solution

  • This sounds like a good use-case for a StringIO object that already implements the file interface. Maybe you can make a file_mock = MagicMock(spec=file, wraps=StringIO('test')). Or you could just have your function accept a file-like object and pass it a StringIO instead of a real file, avoiding the need for ugly monkey-patching.

    Have you looked the mock documentation?

    http://www.voidspace.org.uk/python/mock/compare.html#mocking-the-builtin-open-used-as-a-context-manager