我的模块的结构:
foo:
- load() # from DB
bar:
- check() # with user
- take_action()
我想通过模拟加载和检查来测试take_action(它在执行操作之前基本上加载值并检查用户)。
这是嘲笑:
mock_load = Mock(side_effects=[<>, <>, <>]) # different data sets
mock_check = Mock(return_value=True) # User approval
如何使用patch.multiple
使用Python 2.6实现此目的?
with patch.multiple(??):
# proceed to test
take_action
答案 0 :(得分:10)
简短的回答是,你不能使用patch.multiple()
来做。如patch.multiple中所述,所有参数都将应用于所有创建的模拟,并且所有参数必须是同一对象的属性。您必须通过单个补丁调用来执行此操作。
不幸的是,您使用的是python 2.6,因此您只需使用python: create a "with" block on several context managers和Multiple context `with` statement in Python 2.6中指向的nested
前contextlib
。
使用@patch
作为装饰器可能更简洁明了:
@patch("foo.load",side_effects=["a","b","c"])
@patch("bar.check",return_value=True)
def test_mytest(mock_check,mock_load):
take_action()
assert mock_load.called
assert mock_check.called
如果您在测试类的所有测试中都需要它,您可以装饰该类并在所有测试方法中使用模拟:
@patch("foo.load",side_effects=["a","b","c"])
@patch("bar.check",return_value=True)
class TestMyTest(unittest.TestCase)
def test_mytestA(self,mock_check,mock_load):
take_action()
self.assertTrue(mock_load.called)
self.assertTrue(mock_check.called)
def test_mytestA(self,mock_check,mock_load):
mock_check.return_value = False
take_action()
self.assertTrue(mock_load.called)
self.assertTrue(mock_check.called)
最后,您可以使用with
和contextlib
来完成第一个示例:
from contextlib import nested
with nested(patch("foo.load",side_effects=["a","b","c"]), patch("bar.check",return_value=True)) as (mock_load, mock_check):
take_action()
assert mock_load.called
assert mock_check.called
......或者手工筑巢......
with patch("foo.load",side_effects=["a","b","c"]) as mock_load:
with patch("bar.check",return_value=True)) as mock_check:
take_action()
assert mock_load.called
assert mock_check.called
我觉得装饰器最易读且易于使用。