有两种方法可以做到这一点:使用patch和patch.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'
在这两种情况下,在测试功能完成后,某些fn将被“取消模拟”。
编辑:
为了模拟多个函数,只需向函数中添加更多的decorator并添加参数以接受额外的参数@patch.object(foo, 'some_fn')
@patch.object(foo, 'other_fn')
def test_foo(test_other_fn, test_some_fn):
...
注意,decorator离函数定义越近,它在参数列表中的位置就越早。