2011-12-12 121 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