2011-04-24 71 views
10

是否有可能对属性有side_effect?如果我看看Mock文档,它似乎只能在对象方法上使用。Python:对象属性上的模拟side_effect

我试图测试以下:

def get_object(self): 
    try: 
     return self.request.user.shop 
    except Shop.DoesNotExist: 
     return None 

我想店提出一个DoesNotExist例外。

猜测也许我不够清楚,但我正在谈论的空洞模拟库。

http://www.voidspace.org.uk/python/mock/index.html

+0

什么问题??? – 2011-04-24 08:15:18

+0

是否有可能在房产上有side_effect? – Pickels 2011-04-24 08:24:55

+0

那么我想知道是否有可能在模拟对象的属性上拥有side_effect(模拟库的功能)。在文档中,他们只显示了在方法上执行此操作的示例。由于在我的代码商店没有被调用,副作用不起作用。如果你在理解这个问题时仍然有问题,我可以详细阐述它。 – Pickels 2011-04-24 09:00:15

回答

4

是的,你可以使用属性吧:

In [1]: class ShopDoesNotExist(Exception): 
    ...:  pass 
    ...: 

In [2]: class User(object): 
    ...:  @property 
    ...:  def shop(self): 
    ...:   raise ShopDoesNotExist 
    ...: 
    ...: 

In [3]: u = User() 

In [4]: u.shop 
--------------------------------------------------------------------------- 
ShopDoesNotExist       Traceback (most recent call last) 
+0

有没有办法在一个类的实例上做到这一点? – Pickels 2011-04-24 08:35:03

+0

为什么要将属性添加到单个实例?如果你想要它的条件,只需在属性的方法中使用'if'。 – ThiefMaster 2011-04-24 08:37:02

+0

因此,我可以在测试过程中更换商店以提出异常情况。 – Pickels 2011-04-24 08:39:11

6

值得一提的是,现在存在PropertyMock类:

>>> m = MagicMock() 
>>> p = PropertyMock(side_effect=ValueError) 
>>> type(m).foo = p 
>>> m.foo 
Traceback (most recent call last): 
.... 
ValueError 

这例子是taken from the official site

4

您也可以尝试使用PropertyMock作为new_callable参数来修补相关字段。

实施例:

from unittest import TestCase 
import mock 
from django import models 
from django.core.exceptions import ObjectDoesNotExist 

class Foo(models.Model): 
    # ... 
    @property 
    def has_pending_related(self): 
     try: 
      return self.related_field.is_pending 
     except ObjectDoesNotExist: 
      return False 

class FooTestCase(TestCase): 
    # ... 
    @mock.patch.object(Foo, 'related_field', new_callable=mock.PropertyMock) 
    def test_pending_related(self, related_field): 
     related_field.side_effect = ObjectDoesNotExist 
     foo = Foo() 
     self.assertFalse(foo.has_pending_related)