2011-04-24 57 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)