假设我修补并模拟了某些函数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
?
答案 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")
我写了一篇评论,我认为在这个答案语境中很重要:这是做这些测试的错误方法。在这个测试中,您正在编写纠缠测试和生产代码的电线。
如果您无法重构代码以更模块化和可测试的方式编写代码,则应使用此测试检查行为,并在使用它之后立即重构代码而不更改行为。最后一步是使用重构代码重写测试,然后删除旧测试。