Python模拟 - 模拟几个开放

时间:2012-02-19 12:26:10

标签: python file-io mocking with-statement

阅读本文后:How do I mock an open used in a with statement (using the Mock framework in Python)?

我可以使用:

在python中模拟open函数
with patch(open_name, create=True) as mock_open:
    mock_open.return_value = MagicMock(spec=file)
    m_file = mock_open.return_value.__enter__.return_value
    m_file.read.return_value = 'text1'

    diffman = Diffman()
    diffman.diff(path1, path2)

当我的测试方法使用一个开放语句时,它运行良好。这是我测试的方法:

def diff(self, a, b):
    with open(a, 'r') as old:
        with open(b, 'r') as new:
            oldtext = old.read()
            newtext = new.read()

oldtext和newtext的值相同(此处为'text1')。

我想为oldtext设置'text1',为newtext设置'text2'。

我该怎么做?

2 个答案:

答案 0 :(得分:5)

这是获得所需内容的快捷方式。它有点欺骗,因为被测方法中的两个文件对象是同一个对象,我们只是在每次读取后更改读取调用的返回值。如果您希望文件对象不同,您可以在多个图层中使用相同的技术,但它会非常混乱,并且可能会不必要地掩盖测试的意图。

替换此行:

    m_file.read.return_value = 'text1'

使用:

    reads = ['text1', 'text2']
    m_file.read.side_effect = lambda: reads.pop(0)

答案 1 :(得分:3)

也许一个好的解决方案就是以更好的方式编写代码,以便轻松地测试它。在'diff'的情况下,似乎很容易(没有太多其他上下文,不可否认)将diff作为参数已打开的文件对象。这可能是代码中的一个相当小的变化,并且使测试变得非常简单,因为您可以在测试时轻松地向diff()提供模拟文件对象,而不是试图通过模拟两个相同的实例来跳过内置函数作为在...内部调用的上下文管理器......或其他东西; - )

import StringIO

diff(a, b):
  oldtext = a.read()
  newtext = b.read()

def test_diff():
  a = StringIO.StringIO('text1')
  b = StringIO.StringIO('text2')

  res = diff(a, b)
  <some assertion here>

这适用于您的情况吗?