简体   繁体   English

具有AttributeError和ValueError的Python PropertyMock副作用

[英]Python PropertyMock side effect with AttributeError and ValueError

I am trying to mock a property of a class (@property decorator) and have bumped into this incorrect behaviour: 我试图模拟一个类的属性(@property装饰器)并且碰到了这个不正确的行为:

 >>> from mock import MagicMock, PropertyMock
 >>> m = MagicMock()
 >>> type(m).p = PropertyMock(side_effect=AttributeError)
 >>> m.p
 <MagicMock name='mock.p' id='63150736'>

The correct behaviour is this: 正确的行为是这样的:

 >>> from mock import MagicMock, PropertyMock
 >>> m = MagicMock()
 >>> type(m).p = PropertyMock(side_effect=ValueError)
 >>> m.p
Traceback (most recent call last)
[...]
ValueError

I cannot fathom why setting a different exception is giving me different results. 我无法理解为什么设置一个不同的例外会给我不同的结果。 The expected result in both cases is that the exception should be raised! 两种情况下的预期结果都是应该提出异常! So, the In[4] line should raise an AttributeError . 因此,In [4]行应该引发AttributeError It does not. 它不是。

Anyone care to enlighten me? 有人关心开导我吗?

Addendum : The property I am trying to check does some clever checking to see if the value passed is sane. 附录 :我试图检查的属性做了一些巧妙的检查,看看传递的值是否合理。 If said value is not sane, it returns AttributeError as I understand that this is the correct exception in Python. 如果所述值不合理,则返回AttributeError,因为我理解这是Python中的正确异常。 So, I need to check the code that uses the property for failure as well as success. 所以,我需要检查使用该属性的代码是否失败以及成功。 Thus, using a MagicMock to mock the property and raise said exception. 因此,使用MagicMock来模拟属性并引发异常。 A trivial example would be: 一个简单的例子是:

@x.setter
def x(self, value):
    if value < 0:
         raise AttributeError("Value cannot be negative!")
    self._x = value

I know this question is old, but I've just had the same problem and found this question. 我知道这个问题很老,但我遇到了同样的问题,发现了这个问题。 Also the bug report submitted almost two years ago didn't seem to get any attention, so I thought I'll share the solution I found just in case anybody else will have this problem. 大约两年前提交的错误报告似乎也没有得到任何关注,所以我想我会分享我发现的解决方案以防万一其他人会遇到这个问题。

So, as stated PropertyMock doesn't work with AttributeError set as a side_effect . 因此, side_effectPropertyMock不能将AttributeError设置为side_effect The workaround is to create a simple Mock with a spec attribute set to an empty list like this: 解决方法是创建一个简单的Mock ,其spec属性设置为空list如下所示:

>>> from mock import Mock
>>> m = Mock(spec=[])
>>> m.p
Traceback (most recent call last)
[...]
AttributeError

As stated in the docs : 文档中所述:

spec: This can be either a list of strings or an existing object (a class or instance) that acts as the specification for the mock object. spec:这可以是字符串列表,也可以是充当模拟对象规范的现有对象(类或实例)。 If you pass in an object then a list of strings is formed by calling dir on the object (excluding unsupported magic attributes and methods). 如果传入一个对象,则通过在对象上调用dir来形成字符串列表(不包括不受支持的魔术属性和方法)。 Accessing any attribute not in this list will raise an AttributeError. 访问不在此列表中的任何属性将引发AttributeError。

Er, hold the phone. 呃,拿着电话。 Does this cover your use case? 这是否涵盖您的用例?

>>> import mock
>>> m = mock.MagicMock()
>>> m.p
<MagicMock name='mock.p' id='139756843423248'>
>>> del m.p #!
>>> m.p
Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
     File "/home/ahammel/bin/python/mock-1.0.1-py2.6.egg/mock.py", line 664, in __getattr__
         raise AttributeError(name)
     AttributeError: p

I stumbled across that in the docs while looking for something entirely different. 在找到完全不同的东西时,我在文档中偶然发现了这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM