我试图模拟一个类的属性(@property装饰器)并且碰到了这个不正确的行为:
>>> from mock import MagicMock, PropertyMock
>>> m = MagicMock()
>>> type(m).p = PropertyMock(side_effect=AttributeError)
>>> m.p
<MagicMock name='mock.p' id='63150736'>
Run Code Online (Sandbox Code Playgroud)
正确的行为是这样的:
>>> from mock import MagicMock, PropertyMock
>>> m = MagicMock()
>>> type(m).p = PropertyMock(side_effect=ValueError)
>>> m.p
Traceback (most recent call last)
[...]
ValueError
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么设置一个不同的例外会给我不同的结果.两种情况下的预期结果都是应该提出异常!因此,In [4]行应该提高一个AttributeError.它不是.
有人关心开导我吗?
附录:我试图检查的属性做了一些巧妙的检查,看看传递的值是否合理.如果所述值不合理,则返回AttributeError,因为我理解这是Python中的正确异常.所以,我需要检查使用该属性的代码是否失败以及成功.因此,使用MagicMock来模拟属性并引发异常.一个简单的例子是:
@x.setter
def x(self, value):
if value < 0:
raise AttributeError("Value cannot be negative!")
self._x = value
Run Code Online (Sandbox Code Playgroud)
Max*_*eev 13
我知道这个问题很老,但我遇到了同样的问题,发现了这个问题.大约两年前提交的错误报告似乎也没有得到任何关注,所以我想我会分享我发现的解决方案以防万一其他人会遇到这个问题.
因此,如上所述PropertyMock不适用于AttributeErrorset as a side_effect.解决方法是创建一个简单Mock的spec属性设置为空,list如下所示:
>>> from mock import Mock
>>> m = Mock(spec=[])
>>> m.p
Traceback (most recent call last)
[...]
AttributeError
Run Code Online (Sandbox Code Playgroud)
如文档中所述:
spec:这可以是字符串列表,也可以是充当模拟对象规范的现有对象(类或实例).如果传入一个对象,则通过在对象上调用dir来形成字符串列表(不包括不受支持的魔术属性和方法).访问不在此列表中的任何属性将引发AttributeError.