我正在为我正在开发的api客户端使用一组单元测试中的空洞mock库。我刚刚遇到API更改的问题(并且sdk上的属性被重命名)和我在测试中使用的sdk的模拟版本没有选择它(当我尝试模拟时我希望它们失败属性和方法就不存在于模拟的sdk上)。我正在重写测试以使用spec_set
,但我似乎无法让它们工作。
如果我有一个具有属性MyItemClass
的类name
和一个方法run
,我如何以这样的方式模拟它:如果在sdk中重命名属性或方法我在单元测试中拿起它。
MyItemClass
就是:
class MyItemClass:
...
@property
def name(self):
return self._details.name
def run(self):
... do something ...
return result
目前我正在尝试:
mock_item = mock.MagicMock(spec_set=sdk.MyItemClass)
type(mock_item).name = mock.PropertyMock(return_value="Item title")
mock_item.run = mock.MagicMock(return_value=foobar)
但是这并没有在属性MyItemClass
的{{1}}中重新命名为name
,它只是进行模拟(因此测试通过)。
同样,这段代码(由于PropertyMocks的存储方式,文档说你不应该这样做):
item_name
似乎拿起重命名(并且在设置mock_item = mock.MagicMock(spec_set=sdk.MyItemClass)
mock_item.name = mock.PropertyMock(return_value="Item title")
mock_item.run = mock.MagicMock(return_value=foobar)
时失败),但是当命名被修复时,模拟看起来不像以前那样工作(测试开始失败,因为属性没有返回测试期望的是什么,可能是因为name
的丢弃。
答案 0 :(得分:0)
这看起来像是python模拟库中的一个bug或缺少的功能。我提出了与issue相同的问题,在添加此功能之前,我的原始解决方法是最佳答案:
我使用以下代码解决它:
def add_property(mock_object, property_name, property_value) :
prop = mock.PropertyMock(return_value=property_value)
setattr(type(mock_object), property_name, prop)
# this catches sdk changes if spec_set is used with the MagicMock as
# it will fail if you assign the property to an non-existant attribute
mock_object.attach_mock(prop, property_name)
mock_item = mock.MagicMock(spec_set=sdk.MyItemClass)
add_property(mock_item, 'name', "Item title")
如果删除或重命名属性add_property
,则name
将在attach_mock中失败,然后根据需要中断单元测试。