2012-03-12 62 views
5

试图嘲笑调用pyazure库的django测试,但我不知道如何模拟出PyAzure类的构造函数,以便它不会导致TypeError。有没有更好的方法来模拟生成连接对象的访问库?正确的方法Python模拟__init __()方法,返回一个假类

我试过的其他东西都没有产生TypeError,这意味着我甚至不能开始用实际的返回值测试任何PyAzure连接方法。使用模拟来替换一个工作班的最佳方式是什么?

测试错误:

====================================================================== 
ERROR: test_management_certificate_connect (azure_cloud.tests.ViewsTest) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/Users/bschott/Source/django-nimbis/apps/azure_cloud/tests.py", line 107, in test_management_certificate_connect 
self.cert1.connect() 
File "/Users/bschott/Source/django-nimbis/apps/azure_cloud/models.py", line 242, in connect 
    subscription_id=self.subscription.subscription_id) 
TypeError: __init__() should return None, not 'FakeAzure' 
---------------------------------------------------------------------- 

tests.py:

class ViewsTest(TestCase): 
    def setUp(self): 
    ... 
     self.cert1 = ManagementCertificate.objects.create(
      name="cert1", 
      subscription=self.subscription1, 
      management_cert=File(open(__file__), "cert1.pem"), 
      owner=self.user1) 
    ... 

    class FakeAzure(object): 
     """ testing class for azure """ 
     def list_services(self): 
      return ['service1', 'service2', 'service3'] 
     def list_storages(self): 
      return ['storage1', 'storage2', 'storage3'] 

    @mock.patch.object(pyazure.PyAzure, '__init__') 
    def test_management_certificate_connect(self, mock_pyazure_init): 
     mock_pyazure_init.return_value = self.FakeAzure() 
     self.cert1.connect() 
     assert mock_pyazure_init.called 

models.py

class ManagementCertificate(models.Model): 

    # support connection caching to azure 
    _cached_connection = None 

    def connect(self): 
     """ 
     Connect to the management interface using these credentials. 
     """ 
     if not self._cached_connection: 
      self._cached_connection = pyazure.PyAzure(
       management_cert_path=self.management_cert.path, 
       subscription_id=self.subscription.subscription_id) 
      logging.debug(self._cached_connection) 
     return self._cached_connection 

回答

11

你似乎有一个什么__init__()确实误解。它的目的是初始化一个早先已经创建的实例。 __init__()的第一个参数是self,它是实例,所以当调用__init__()时,您可以看到它已被分配。

__init__()之前调用方法__new__()来创建实际实例。然而,我认为用模拟课替换整个班级,而不是嘲笑单一方法会容易得多。

+2

+1改为模拟类。 – 2012-03-12 16:37:22

+0

感谢您的指点。我知道替换__init__返回的对象只是感觉不对,但在模拟文档中找不到它们在哪里模拟实际的类。类方法,是的,但不是类本身。 现在看起来很明显,但它并没有在一小时前:-)。 @ mock.patch.object(pyazure, 'PyAzure',规格= pyazure.PyAzure) DEF test_management_certificate_connect(个体,mock_pyazure): self.cert1.connect() mock_pyazure.assert_called_with( '富', 'bar' 的) – bfschott 2012-03-12 17:47:02

相关问题