有两种方法可以做到这一点;有补丁和补丁.object
Patch 假定您不是直接导入对象,而是您正在测试的对象正在使用它,如下所示
#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,如下:
#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 都将在测试功能完成后“取消模拟”。
编辑:为了模拟多个函数,只需向函数添加更多装饰器并添加参数以接收额外参数
@patch.object(foo, 'some_fn')
@patch.object(foo, 'other_fn')
def test_foo(test_other_fn, test_some_fn):
...
请注意,装饰器越接近函数定义,它在参数列表中的位置就越早。