Python模拟多次调用并返回不同结果
我想让一个特定的属性函数在每次调用时返回不同的结果,也就是说,连续调用时结果要不一样。
在下面的例子中,我希望第一次调用时返回5,第二次调用时返回10。
比如:
import mock
class A:
def __init__(self):
self.size = 0
def increment(self, amount):
self.size += amount
return amount
@mock.patch("A.increment")
def test_method(self, mock_increment):
def diff_inc(*args):
def next_inc(*args):
#I don't know what belongs in __some_obj__
some_obj.side_effect = next_inc
return 10
return 5
mock_increment.side_effect = diff_inc
下面这个页面几乎包含了我需要的所有内容,唯一的问题是它假设调用者是一个名为“mock”的对象,但这并不能保证。
http://mock.readthedocs.org/en/latest/examples.html#multiple-calls-with-different-effects
4 个回答
1
你可以使用 patch
并设置模块的绝对路径。
from unittest.mock import patch
@patch("src.module2.requests.post")
@patch("src.module1.requests.get")
def test_mock(self, mock_get, mock_post):
data = {}
mock_post.return_value.status_code = 200
mock_post.return_value.json.return_value = data
mock_get.return_value.json.return_value = data
在补丁中使用的顺序必须与方法的模拟参数保持一致,module1 指的是 mock_get,而 module2 指的是 mock_post。
6
我觉得从列表中取出值的方法会更简单明了。下面这个例子适合你想要进行的测试。
另外,我之前在使用mock库时遇到过一些困难,发现使用mock.patch.object()
这个方法通常更容易上手。
import unittest
import mock
class A:
def __init__(self):
self.size = 0
def increment(self, amount):
self.size += amount
return amount
incr_return_values = [5, 10]
def square_func(*args):
return incr_return_values.pop(0)
class TestMock(unittest.TestCase):
@mock.patch.object(A, 'increment')
def test_mock(self, A):
A.increment.side_effect = square_func
self.assertEqual(A.increment(1), 5)
self.assertEqual(A.increment(-20), 10)
12
我测试过了,这个应该可以用
import mock
...
...
@mock.patch.object(ClassB, 'method_2')
@mock.patch.object(ClassA, 'method_1')
def test_same_method_multi_return_value(self, method_1, method_2):
# type: () -> None
method_1.return_value = 'Static value'
method_1.side_effect = [
'Value called by first time'
'Value called by second time'
'...'
]
版本
https://mock.readthedocs.io/en/latest/
mock>=2.0.0,<3.0
128
你可以直接把一个可迭代的对象传给side effect,这样每次你调用的时候,它就会遍历这个值的列表。
@mock.patch("A.increment")
def test_method(self, mock_increment):
mock_increment.side_effect = [5,10]
self.assertEqual(mock_increment(), 5)
self.assertEqual(mock_increment(), 10)