在Python的模拟中修补函数调用中的一个实例

时间:2016-01-19 11:54:24

标签: python unit-testing mocking python-mock

假设我修补并模拟了某些函数foo(),它实现了读取多个文件。我们有多个open()来电:

def foo():
    a=open("stuff.txt")
    b=open("another_thing.txt")
    c=open("last_one.txt")

如果我mock.patch("__builtin__.open", return_value='kaboom'),第一次出现的open()将被修补,一个读取文件名为“stuff.txt”。

如果我需要修补open()中的第二个(任何其他)foo()来电来模拟来自阅读的return_value,请说another_thing.txt

2 个答案:

答案 0 :(得分:2)

可以通过side_effect参数来模拟,但我不建议。相反,重构你的代码,以便每个开放调用都在一个单独的函数中发生,你可以单独修补它。

a = open_stuff()
b = open_another_thing()
c = open_last_one()

答案 1 :(得分:1)

因为你不喜欢最好的答案(丹尼尔的答案),我可以通过side_effect告诉你如何做到这一点:

>>> import mock
>>> with mock.patch("__builtin__.open", side_effect = ["kaboom", "more","moremore"]):
...     assert "kaboom" == open("stuff.txt")
...     assert "more" == open("another_thing.txt")
...     assert "moremore" == open("last_one.txt")

或更好

>>> with mock.patch("__builtin__.open", side_effect = lambda name, *args: name):
...     assert "stuff.txt" == open("stuff.txt")
...     assert "another_thing.txt" == open("another_thing.txt")
...     assert "last_one.txt" == open("last_one.txt")

我写了一篇评论,我认为在这个答案语境中很重要:这是做这些测试的错误方法。在这个测试中,您正在编写纠缠测试和生产代码的电线。

如果您无法重构代码以更模块化和可测试的方式编写代码,则应使用此测试检查行为,并在使用它之后立即重构代码而不更改行为。最后一步是使用重构代码重写测试,然后删除旧测试。