I'm currently trying to mock out the open() built in method in Python for a test. However, I always end up getting a crash and this resulting message:
File "/opt/home/venv/lib/python2.7/site-packages/nose-1.3.0-py2.7.egg/nose/result.py", line 187, in _exc_info_to_string
return _TextTestResult._exc_info_to_string(self, err, test)
File "/opt/python-2.7.3/lib/python2.7/unittest/result.py", line 164, in _exc_info_to_string
msgLines = traceback.format_exception(exctype, value, tb)
File "/opt/python-2.7.3/lib/python2.7/traceback.py", line 141, in format_exception
list = list + format_tb(tb, limit)
File "/opt/python-2.7.3/lib/python2.7/traceback.py", line 76, in format_tb
return format_list(extract_tb(tb, limit))
File "/opt/python-2.7.3/lib/python2.7/traceback.py", line 101, in extract_tb
line = linecache.getline(filename, lineno, f.f_globals)
File "/opt/home/venv/lib/python2.7/linecache.py", line 14, in getline
lines = getlines(filename, module_globals)
File "/opt/home/venv/lib/python2.7/linecache.py", line 40, in getlines
return updatecache(filename, module_globals)
File "/opt/home/venv/lib/python2.7/linecache.py", line 127, in updatecache
with open(fullname, 'rU') as fp:
AttributeError: __exit__
Here is my test code:
m = mox.Mox()
m.StubOutWithMock(__builtin__, 'open')
mock_file = m.CreateMock(__builtin__.file)
open(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(mock_file)
mock_file.write(mox.IgnoreArg()).MultipleTimes()
mock_file.close()
write_file_method()
So, the AttributeError: __enter__ is raised when using a with statement with a class that does not have the __enter__ method. You can simulate the AttributeError: __enter__ error message by creating a ContextManager without the __enter__ method: >>> class ContextManager: ...
side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT , the return value of this function is used as the return value.
__exit__
is the method that gets called when you try to close a file. Your mock file does not handle mock_file.close()
, just open()
. You'll need to mock the close
method too.
Edit:
On second though, why do you want to mock open
? AFAIK you shouldn't be doing that method. The method under test should take an open stream (instead of a filename, for instance). In production code, clients are responsible for opening a file (e.g. pickle.dump
). In your tests, you pass in a StringIO
, or a mock object that supports writing.
Edit 2: I would split your method in two and test each bit separately.
StringIO
and write to that, so your tests can then verify the correct thing has been written.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