我正在测试一个方法geodata_collect._request_loc_data()
,并在该方法中调用另一个方法geodata_collect.utils.loadJSON(...)
,我需要对其进行模拟,以便对第一个提到的方法进行单元测试。
我的问题是我需要geodata_collect.utils.loadJSON(...)
在geodata_collect._request_loc_data()
内第三次调用时返回不同的值。
为了做到这一点,我一直在探索MagicMock
和side_effect
。
mock = MagicMock()
mock.side_effect = [self._create_request_dict(next_page_token=True),
self._create_request_dict(next_page_token=True), self._create_request_dict()]
with patch('geodata_collect.utils.loadJSON',return_value=mock):
geodata_collect._request_loc_data()
但是,当从geodata_collect.utils.loadJSON(...)
内调用geodata_collect._request_loc_data()
时,将返回MagicMock类,而不是实际值。
<MagicMock id='140642209064888'>
应该返回什么:
{'status': 'OK', 'next_page_token': 'Next Page EXISTS!!', 'result': [1, 2, 3, 4, 5]}
{'status': 'OK', 'next_page_token': 'Next Page EXISTS!!', 'result': [1, 2, 3, 4, 5]}
{'status': 'OK', 'result': [1, 2, 3, 4, 5]}
答案 0 :(得分:4)
您已将调用的返回值设置为模拟对象。那就是将要归还的东西!您为该调用结果的调用设置了返回值(副作用),因此geodata_collect.utils.loadJSON()()
。
设置side_effect
argument in the patch()
call:
results = [
self._create_request_dict(next_page_token=True),
self._create_request_dict(next_page_token=True),
self._create_request_dict()]
with patch('geodata_collect.utils.loadJSON', side_effect=results):
geodata_collect._request_loc_data()
或者在进入上下文管理器时返回的模拟对象上的side_effect
attribute:
with patch('geodata_collect.utils.loadJSON', side_effect=results) as load_mock:
load_mock.side_effect = [
self._create_request_dict(next_page_token=True),
self._create_request_dict(next_page_token=True),
self._create_request_dict()]
geodata_collect._request_loc_data()
捕获模拟对象patch()
上下文管理器创建as <name>
通常是一个好主意,因为你现在可以访问它来断言它是否被调用。
您还可以传入您之前创建的MagicMock
实例,只需将其作为第二个参数传入,或使用名称new
:
mock = MagicMock()
mock.side_effect = [self._create_request_dict(next_page_token=True),
self._create_request_dict(next_page_token=True), self._create_request_dict()]
with patch('geodata_collect.utils.loadJSON', mock): # or new=mock
geodata_collect._request_loc_data()
然后 patch()
将geodata_collect.utils.loadJSON
替换为该实例,并且调用它将使用side_effect
列表集。