<br><br><div class="gmail_quote">On Sat, Oct 2, 2010 at 1:34 PM, W. Matthew Wilson <span dir="ltr"><<a href="mailto:matt@tplus1.com">matt@tplus1.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
I'm using the mock package version 7. Here's the production code I<br>
want to test:<br>
<br>
def to_html(self, filepath):<br>
"""<br>
Write this bag out as HTML to a file at filepath.<br>
"""<br>
<br>
with open(os.path.join(filepath, self.html_filename), 'w') as f:<br>
f.write(self.html)<br>
<br>
And here's the test for that to_html method. I'm using mock.patch to<br>
substitute a MagicMock object in for the results of the call to<br>
open(...).<br>
<br>
@mock.patch(<br>
'__builtin__.open',<br>
mock.Mock(return_value=mock.MagicMock(spec=file)))<br>
def test_to_html():<br>
<br>
global b<br>
b.to_html('bogus filepath')<br>
<br>
It took me a long time to figure out how to do this. And that makes<br>
me think maybe there's a much simpler and cleaner approach out there.<br>
<br>
My example is different than the one in the documentation<br>
(<a href="http://www.voidspace.org.uk/python/mock/magicmock.html" target="_blank">http://www.voidspace.org.uk/python/mock/magicmock.html</a>) because that<br>
one looks like this:<br>
<br>
>>> from mock import Mock<br>
>>> mock = Mock()<br>
>>> mock.__enter__ = Mock()<br>
>>> mock.__exit__ = Mock()<br>
>>> mock.__exit__.return_value = False<br>
>>> with mock:<br>
... pass<br>
<br>
In that one, mock needs to support calls to __enter__ and __exit__.<br>
<br>
where this one is mine:<br>
<br>
with open(...) as f:<br>
<br>
In mine, the open function needs to return something that can support<br>
calls to __enter__ and __exit__.<br>
<br>
So, that's why I'm making a regular mock.Mock object that then returns<br>
a fancy mock.MagicMock(spec=file) object.<br>
<br>
Like I said, it took me a long time to figure this out, and I find it<br>
confusing to read, so I hope there's some more elegant solution out<br>
there.<br>
<br>
Great library, by the way.<br>
<br>
Matt<br><br></blockquote><div><br></div><div>I tend to dislike mocking out anything in __builtins__ as that can really interfere with other code including code in the test harness at times depending on what exactly it is doing.</div>
<div><br></div><div>When possible, assuming you control the code that is being tested, I recommend refactoring the original code as such:</div><div><br></div><div>def to_html(self, filepath, _open=open):</div><div> ...</div>
<div> with _open(...) as x:</div><div> ...</div><div><br></div><div>To test this method, pass in your own fake or mock open function that returns an appropriate stringio for testing that you can validate the contents of later.</div>
<div><br></div><div>-gps</div><div><br></div></div>