2012-12-04 67 views
1

我有几个测试用例类在我的Django应用程序。在其中的一些中,我用@ mock.patch来嘲笑一个调用外部资源的函数,这很好用。在我的测试套件的一个TestCase的,让我们叫它B(),依赖于外部资源,所以我不希望它嘲笑了,我不加装饰。它看起来像这样:Unmocking在Django单元中的嘲笑对象测试

@mock.patch("myapp.external_resource_function", new=mock.MagicMock) 
class A(TestCase): 
    # tests here 

class B(TestBase): 
    # tests here which depend on external_resource_function 

当我独立地测试B时,事情按预期工作。然而,当我运行这两个测试一起,A先运行,但功能依然嘲笑出B.我怎么能unmock这一呼吁?我试过重新加载模块,但它没有帮助。

回答

5

补丁start and stop methods。根据我可以从你所提供的代码中看到的,我会删除装饰,并使用在你的类的链接中找到的安装和拆卸方法。

class A(TestCase): 
    def setUp(self): 
    self.patcher1 = patch('myapp.external_resource_function', new=mock.MagicMock) 
    self.MockClass1 = self.patcher1.start() 

    def tearDown(self): 
    self.patcher1.stop() 

    def test_something(self): 
    ... 

>>> A('test_something').run() 
+1

谢谢,开始和停止是我需要的! – velotron

+1

如果一个测试需要一个模拟,另一个不需要?除了在每个单元测试中打补丁/开始/停止之外,没有其他方法可以做到这一点吗? – Ethereal

0

伟大的答案。关于Ethereal的问题,修补程序对象在使用时非常灵活。

这里有接近需要不同的补丁测试的一种方法。您仍可以使用setUp和tearDown,但不能执行patch.start/stop位。

你开始()在每个测试补丁,并使用finally语句,以确保他们得到停止()。

补丁还支持上下文管理的东西,所以这是另一种选择,这里没有显示。

class A(TestCase): 
    patcher1 = patch('myapp.external_resource_function', new=mock.MagicMock) 
    patcher2 = patch('myapp.something_else', new=mock.MagicMock) 


    def test_something(self): 

     li_patcher = [self.patcher1] 
     for patcher in li_patcher: 
      patcher.start() 


     try: 
      pass 
     finally: 
      for patcher in li_patcher: 
       patcher.stop() 


    def test_something_else(self): 

     li_patcher = [self.patcher1, self.patcher2] 
     for patcher in li_patcher: 
      patcher.start() 

     try: 
      pass 
     finally: 
      for patcher in li_patcher: 
       patcher.stop()