python - 如何在 Python 中使用模拟文件对象进行单元测试?

标签 python unit-testing python-2.7 mocking

我有一个类,我通过给一个文件名来实例化它,比如 parser = ParserClass('/path/to/file'),然后我调用 parser.parse() 打开并读取文件的方法。
现在我想进行单元测试,如果里面发生了什么不好的事情:

with open(filename, 'rb') as fp:
    // do something

将引发正确的异常,所以我想像这样模拟 __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()

但这给了我一个AttributeError: StringIO instance has no attribute '__exit__'
我认为 StringIO 的行为与文件对象完全一样,但事实并非如此。

如何使用给定内容 (test_lines) 和模拟对象测试此方法?我应该改用什么?

最佳答案

您可以子类化 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(...)

粗略推测:如果 StringIO 对象是 file 对象的替代品 except 因为缺少上下文管理器,我想知道是否这会起作用:

class ContextualStringIO(StringIO, file):
    pass

ContextualStringIO 继承了它可以从 StringIO 进行的文件操作,但其他一切都是从 file 继承的。它看起来很优雅,但可能需要大量测试(或者需要更熟悉 Python 内部结构的人来解释为什么这行不通)。

关于python - 如何在 Python 中使用模拟文件对象进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17090151/

相关文章:

python - 使用 google-api-python-client 拉超时

javascript - 数据从 HTML 文本输入传递到 python 脚本

使用 CMake 编译测试可执行文件

unit-testing - Moq 和 Rhino 模拟之间的语法比较

angularjs - 测试 mousedown、mousemove、mouseup Angular

python - 字典的子类化; dict.update 返回不正确的值 - python bug?

Python 显示图像 - AttributeError

python - MYSQL Db 中的 Django 模型时间戳

python - Python 中的每类常量

python - * 参数的 Itertools