如何使用此路径ablib.Pin
模拟课程?如何在Pin上模拟实例的属性?我会说它应该像这样工作:
mock = MagicMock()
mock.Pin = MagicMock()
mock.Pin.kernel_id = 'N21'
mock.Pin.set_value.return_value = True
mock.Pin.get_value.return_value = 3
modules = {
'ablib': mock,
'ablib.Pin': mock.Pin,
}
patcher = patch.dict('sys.modules', modules)
patcher.start()
当我创建一个Pin实例并调用get_value
或set_value
时,我得到了一个MockInstance而不是True
或3
。
>>> p = Pin()
>>> p.set_value(3)
<MagicMock name='mock.Pin().set_value(3)' id='47965968'>
>>> p.kernel_id
<MagicMock name='mock.Pin().kernel_id' id='49231056'>
当我直接在kernel_id
上致电Pin
时,我得到了我需要的结果。
>>> Pin.kernel_id
'N21'
如何以我从实例ablib.Pin()获取我想要的值的方式模拟ablib.Pin
答案 0 :(得分:1)
以下是对代码进行最少更改的工作版本:
from unittest.mock import patch, MagicMock
mock = MagicMock()
mock.Pin().kernel_id = 'N21'
mock.Pin().set_value.return_value = True
mock.Pin().get_value.return_value = 3
modules = {
'ablib': mock
}
patcher = patch.dict('sys.modules', modules)
patcher.start()
测试:
>>> import ablib
>>> ablib.Pin
<MagicMock name='mock.Pin' id='139917634188240'>
>>> ablib.Pin
<MagicMock name='mock.Pin' id='139917634188240'>
>>> ablib.Pin()
<MagicMock name='mock.Pin()' id='139917634233616'>
>>> ablib.Pin()
<MagicMock name='mock.Pin()' id='139917634233616'>
>>> p = ablib.Pin()
>>> p.set_value(3)
True
>>> p.kernel_id
'N21'
请注意,我已从字典中删除了mock.Pin = MagicMock()
并删除了mock.Pin
。当您访问现有的MagicMock属性或调用它时,默认情况下会创建新的MagicMock实例。下次执行该操作时将返回相同的实例。因此,无需为mock.Pin
(针对Pin类),mock.Pin()
(针对Pin实例)明确创建MagicMock,并将其注册到patch.dict()
。只需注册mock
即可。
感谢patch.dict()
即使模块ablib
不存在也能正常工作。我认为使用patch()
和patch.object()
无法实现。然而,对于真正的单元测试,我使用patch()
来模拟一个类,并使用patch.object()
来模拟某个特定测试或一组测试的实例的属性。当我需要模拟整个模块时,我并没有处于这种情况,但我对单元测试和Python都很陌生。