[TIP] Is this the best way to mock out a call to with open('foo') as f?
W. Matthew Wilson
matt at tplus1.com
Sat Oct 2 13:34:05 PDT 2010
I'm using the mock package version 7. Here's the production code I
want to test:
def to_html(self, filepath):
"""
Write this bag out as HTML to a file at filepath.
"""
with open(os.path.join(filepath, self.html_filename), 'w') as f:
f.write(self.html)
And here's the test for that to_html method. I'm using mock.patch to
substitute a MagicMock object in for the results of the call to
open(...).
@mock.patch(
'__builtin__.open',
mock.Mock(return_value=mock.MagicMock(spec=file)))
def test_to_html():
global b
b.to_html('bogus filepath')
It took me a long time to figure out how to do this. And that makes
me think maybe there's a much simpler and cleaner approach out there.
My example is different than the one in the documentation
(http://www.voidspace.org.uk/python/mock/magicmock.html) because that
one looks like this:
>>> from mock import Mock
>>> mock = Mock()
>>> mock.__enter__ = Mock()
>>> mock.__exit__ = Mock()
>>> mock.__exit__.return_value = False
>>> with mock:
... pass
In that one, mock needs to support calls to __enter__ and __exit__.
where this one is mine:
with open(...) as f:
In mine, the open function needs to return something that can support
calls to __enter__ and __exit__.
So, that's why I'm making a regular mock.Mock object that then returns
a fancy mock.MagicMock(spec=file) object.
Like I said, it took me a long time to figure this out, and I find it
confusing to read, so I hope there's some more elegant solution out
there.
Great library, by the way.
Matt
--
W. Matthew Wilson
matt at tplus1.com
http://tplus1.com
More information about the testing-in-python
mailing list