2011-12-12 174 views
45

我試圖在使用富有想象力的名稱Mock testing library測試Django應用程序時嘲笑某事。我似乎無法完成它的工作,我試圖做到這一點:使用模擬修補程序來模擬實例方法

models.py 

from somelib import FooClass 

class Promotion(models.Model): 
    foo = models.ForeignKey(FooClass) 
    def bar(self): 
     print "Do something I don't want!" 


test.py 

class ViewsDoSomething(TestCase): 
    view = 'my_app.views.do_something' 

    def test_enter_promotion(self): 
     @patch.object(my_app.models.FooClass, 'bar') 
     def fake_bar(self, mock_my_method): 
      print "Do something I want!" 
      return True 

     self.client.get(reverse(view)) 

我在做什麼錯?

+0

'''bar'''實際上是一個 「實例方法」,其唯一的參數是'''self' ''。要成爲一個類方法,它需要用''cls'''來參數化,並且可以調用爲'''Promotion.foo()'''。 – cavaunpeu

+0

可修補對象需要像這樣引用: '@ patch.object('my_app.models.FooClass','bar')' – Lasma

+0

@cavaunpeu - not(just)用'cls'參數化,但更重要的是(自'self'和'cls'並不意味着Python中任何特殊的東西),用'@ classmethod'裝飾 – dwanderson

回答

21

啊我很困惑在哪裏應用補丁裝飾。修正:

class ViewsDoSomething(TestCase): 
    view = 'my_app.views.do_something' 

    @patch.object(my_app.models.FooClass, 'bar') 
    def test_enter_promotion(self, mock_method): 
     self.client.get(reverse(view)) 
+14

你在哪裏建立模擬方法和假實現之間的連接? – physicalattraction

27

要添加到試劑盒的回答,指定一個第三參數patch.object()允許指定嘲笑對象/方法。否則,使用默認的MagicMock對象。

def fake_bar(self): 
     print "Do something I want!" 
     return True 

    @patch.object(my_app.models.FooClass, 'bar', fake_bar) 
    def test_enter_promotion(self): 
     self.client.get(reverse(view)) 
     # Do something I want! 

需要注意的是,如果指定的嘲諷對象,則默認MagicMock()不再傳遞到修補對象 - 例如不再:

def test_enter_promotion(self, mock_method): 

而是:

def test_enter_promotion(self): 

http://www.voidspace.org.uk/python/mock/patch.html#patch-object