kis*_*rgy 9 python unit-testing mocking python-2.7
我有一个类,我通过给出一个文件名来实例化parser = ParserClass('/path/to/file'),然后我调用parser.parse()打开并读取文件的方法.
现在我想进行单元测试,如果内部发生了不好的事情:
with open(filename, 'rb') as fp:
// do something
Run Code Online (Sandbox Code Playgroud)
将引发正确的异常,所以我想嘲笑__builtin__.open这样:
from mock import MagicMock, patch
from StringIO import StringIO
test_lines = StringIO("""some test lines, emulating a real file content""")
mock_open = MagicMock(return_value=test_lines)
with patch('__builtin__.open', mock_open):
self.mock.parse()
Run Code Online (Sandbox Code Playgroud)
但这给了我一个AttributeError: StringIO instance has no attribute '__exit__'.
我认为StringIO的行为与文件对象完全相同,但似乎并非如此.
如何使用模拟对象的给定内容(test_lines)测试此方法?我应该用什么呢?
che*_*ner 10
您可以子类化StringIO以提供上下文管理器:
class ContextualStringIO(StringIO):
def __enter__(self):
return self
def __exit__(self, *args):
self.close() # icecrime does it, so I guess I should, too
return False # Indicate that we haven't handled the exception, if received
test_lines = ContextualStringIO(...)
Run Code Online (Sandbox Code Playgroud)
总的猜测:如果StringIO对象是插入式替代file物,除了为缺乏上下文管理的,我不知道这会工作:
class ContextualStringIO(StringIO, file):
pass
Run Code Online (Sandbox Code Playgroud)
ContextualStringIO继承了它可以从哪些文件操作StringIO,但其他一切都是从中继承的file.它看起来很优雅,但可能需要进行大量测试(或者更熟悉Python内部的人来解释为什么这不起作用).
这是一个StringIO未实现上下文管理器协议的已知问题.
一个常见的配方如下:
from contextlib import contextmanager
@contextmanager
def StringIO():
"""Add support for 'with' statement to StringIO - http://bugs.python.org/issue1286
"""
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
sio = StringIO()
try:
yield sio
finally:
sio.close()
Run Code Online (Sandbox Code Playgroud)
它实现了上下文管理器协议,StringIO并允许它在with语句中使用.
更新嗯,我刚刚发现它的存在mock_open可以直接从字符串读取,所以它可能是要走的路.
| 归档时间: |
|
| 查看次数: |
9618 次 |
| 最近记录: |