AttributeError:__ exit__当我试图模拟构建函数时

use*_*332 7 python unit-testing mocking mox

我目前正在尝试用Python模拟open()内置方法进行测试.但是,我总是得到一个崩溃和这个结果消息:

   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__
Run Code Online (Sandbox Code Playgroud)

这是我的测试代码:

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()
Run Code Online (Sandbox Code Playgroud)

mba*_*rov 4

__exit__是当您尝试关闭文件时调用的方法。您的模拟文件不处理mock_file.close(),只是open(). 您还需要模拟该close方法。


编辑:

其次,你为什么要嘲笑open?AFAIK 你不应该这样做。被测试的方法应该采用一个开放的流(例如,而不是文件名)。在生产代码中,客户端负责打开文件(例如pickle.dump)。在您的测试中,您传入一个StringIO, 或一个支持写入的模拟对象。


编辑2:我会将你的方法分成两部分并分别测试每一位。

  • 创建文件:在调用此方法之前检查该文件是否不存在,然后检查该文件是否存在。有人可能会说这样的单行方法不值得测试。
  • 写入文件:见上文。创建一个StringIO并写入它,以便您的测试可以验证是否已写入正确的内容。

  • 我不认为这是“打开”/“关闭”接口,至少现在还不是。看起来问题是他没有嘲笑上下文管理器接口,即“__enter__”和“__exit__”。仅供参考,关闭文件时不会调用“__exit__”,反之亦然。退出上下文管理器(“with”块)时会调用“__exit__”,然后调用“close”。看起来测试代码中的实际错误正在被“nose”吞噬,因为“nose”正在尝试打开一个文件以使用上下文管理器语法写入错误,但修补后的“open”不支持它。 (3认同)