简体   繁体   English

Python模拟 - 模拟几个开放

[英]Python Mock - Mocking several open

After reading this : How do I mock an open used in a with statement (using the Mock framework in Python)? 阅读本文后: 如何模拟with语句中使用的open(使用Python中的Mock框架)?

I'm able to mock the open function in python using : 我可以使用以下方法在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)

It works well when my tested method used one open statement. 当我的测试方法使用一个开放语句时,它运行良好。 Here is my tested method : 这是我测试的方法:

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

The values of oldtext and newtext are the same ('text1' here). oldtext和newtext的值相同(此处为'text1')。

I would like to have 'text1' for the oldtext and 'text2' for the newtext. 我想为oldtext设置'text1',为newtext设置'text2'。

How can I do this ? 我怎样才能做到这一点 ?

Here's a quick way of getting what you want. 这是获得所需内容的快捷方式。 It cheats a little bit because the two file objects in the method under test are the same object and we're just changing the return value of the read call after each read. 它有点欺骗,因为被测方法中的两个文件对象是同一个对象,我们只是在每次读取后更改读取调用的返回值。 You can use the same technique in multiple layers if you want the file objects to be different, but it will be quite messy and it may disguise the intent of the test unnecessarily. 如果您希望文件对象不同,您可以在多个层中使用相同的技术,但它会非常混乱,并且可能会不必要地掩盖测试的意图。

Replace this line: 替换此行:

m_file.read.return_value = 'text1'

with: 有:

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

Perhaps a good possible solution is just to write the code in a way that better lends itself to easily testing it. 也许一个好的解决方案就是以更好的方式编写代码,以便轻松地测试它。 In the case of 'diff', it seems easy enough (not having much other context, admittedly) to have diff take as arguments already-opened file objects. 在'diff'的情况下,似乎很容易(没有太多其他上下文,不可否认)将diff作为参数已打开的文件对象。 This is likely a fairly small change to make in the code, and makes testing very easy, since you can then easily provide mock file objects to diff() when you test it, instead of trying to jump through hoops mocking two instances of the same builtin function as a context manager called within... itself... or something ;-) 这可能是代码中的一个相当小的变化,并且使测试变得非常简单,因为您可以在测试时轻松地向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>

Would that work for your case? 那对你的情况有用吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM