使用 python 的模拟 patch.object 更改在另一个方法中调用的方法的返回值
问题描述
是否可以模拟在我尝试测试的另一个函数中调用的函数的返回值?我希望模拟方法(将在我正在测试的许多方法中调用)在每次调用时返回我指定的变量.例如:
Is it possible to mock a return value of a function called within another function I am trying to test? I would like the mocked method (which will be called in many methods I'm testing) to returned my specified variables each time it is called. For example:
class Foo:
def method_1():
results = uses_some_other_method()
def method_n():
results = uses_some_other_method()
在单元测试中,我想用mock来改变uses_some_other_method()
的返回值,这样在Foo
中任何时候调用它都会返回我在 @patch.object(...)
In the unit test, I would like to use mock to change the return value of uses_some_other_method()
so that any time it is called in Foo
, it will return what I defined in @patch.object(...)
解决方案
有两种方法可以做到这一点;带补丁和带补丁.object
There are two ways you can do this; with patch and with patch.object
Patch 假定您不是直接导入对象,而是您正在测试的对象正在使用它,如下所示
Patch assumes that you are not directly importing the object but that it is being used by the object you are testing as in the following
#foo.py
def some_fn():
return 'some_fn'
class Foo(object):
def method_1(self):
return some_fn()
#bar.py
import foo
class Bar(object):
def method_2(self):
tmp = foo.Foo()
return tmp.method_1()
#test_case_1.py
import bar
from mock import patch
@patch('foo.some_fn')
def test_bar(mock_some_fn):
mock_some_fn.return_value = 'test-val-1'
tmp = bar.Bar()
assert tmp.method_2() == 'test-val-1'
mock_some_fn.return_value = 'test-val-2'
assert tmp.method_2() == 'test-val-2'
如果是直接导入要测试的模块,可以使用patch.object,如下:
If you are directly importing the module to be tested, you can use patch.object as follows:
#test_case_2.py
import foo
from mock import patch
@patch.object(foo, 'some_fn')
def test_foo(test_some_fn):
test_some_fn.return_value = 'test-val-1'
tmp = foo.Foo()
assert tmp.method_1() == 'test-val-1'
test_some_fn.return_value = 'test-val-2'
assert tmp.method_1() == 'test-val-2'
在这两种情况下 some_fn 都将在测试功能完成后取消模拟".
In both cases some_fn will be 'un-mocked' after the test function is complete.
为了模拟多个函数,只需在函数中添加更多装饰器并添加参数以接收额外的参数
In order to mock multiple functions, just add more decorators to the function and add arguments to take in the extra parameters
@patch.object(foo, 'some_fn')
@patch.object(foo, 'other_fn')
def test_foo(test_other_fn, test_some_fn):
...
请注意,装饰器越接近函数定义,它在参数列表中的位置就越早.
Note that the closer the decorator is to the function definition, the earlier it is in the parameter list.
相关文章