在 Python 的 Mock 中修补一次函数调用
Patching one occurrence on the function call in Python's 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".
的文件
如果我需要修补 foo()
中的第二个(任何其他)open()
调用以模拟 return_value 阅读,比如 another_thing.txt
?
可以通过 Mock 的 side_effect
参数来做到这一点,但我不建议这样做。相反,重构您的代码,以便每个打开的调用都发生在一个单独的函数中,您可以单独修补它。
a = open_stuff()
b = open_another_thing()
c = open_last_one()
因为你不喜欢最佳答案(大牛的那个)我可以告诉你怎么做 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")
我写了一条我认为在这个答案上下文中很重要的评论:这是进行此类测试的错误方法。在此测试中,您正在编写将测试和生产代码纠缠在一起的连线。
如果您无法重构您的代码以以更模块化和可测试的方式编写它,您应该使用此测试来检查行为,并在使用它之后立即重构您的代码而不改变行为。最后一步是使用重构代码重写测试,然后删除旧测试。
假设我修补并模拟了某个实现读取多个文件的函数 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".
如果我需要修补 foo()
中的第二个(任何其他)open()
调用以模拟 return_value 阅读,比如 another_thing.txt
?
可以通过 Mock 的 side_effect
参数来做到这一点,但我不建议这样做。相反,重构您的代码,以便每个打开的调用都发生在一个单独的函数中,您可以单独修补它。
a = open_stuff()
b = open_another_thing()
c = open_last_one()
因为你不喜欢最佳答案(大牛的那个)我可以告诉你怎么做 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")
我写了一条我认为在这个答案上下文中很重要的评论:这是进行此类测试的错误方法。在此测试中,您正在编写将测试和生产代码纠缠在一起的连线。
如果您无法重构您的代码以以更模块化和可测试的方式编写它,您应该使用此测试来检查行为,并在使用它之后立即重构您的代码而不改变行为。最后一步是使用重构代码重写测试,然后删除旧测试。