2012-03-12 11 views
5

Pyjureテストのためにpyazureライブラリへの呼び出しをモックしようとしましたが、PyAzureクラスのコンストラクタをモックアウトして、型エラー。接続オブジェクトを生成するアクセスライブラリを模擬してアプローチするより良い方法はありますか?適切な方法pythonモック__init偽のクラスを返す__()メソッド

私がNone以外で試したことは、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:あなたは__init__()が何をするかについての誤解があるようだ

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__()の最初の引数はが呼び出されたときにすでに割り当てられていたので、インスタンスであるselfです。

__init__()の前に呼び出され、実際のインスタンスを作成するメソッド__new__()があります。しかし、単一のメソッドを嘲笑するのではなく、クラス全体を模擬クラスで置き換える方がはるかに簡単だと思います。

+2

+1代わりにクラスをモックしてください。 –

+0

ポインタをありがとう。私は__init__によって返されたオブジェクトを置き換えたことが間違っていることを知っていましたが、実際のクラスを模擬した場所はどこにもありません。クラスメソッド、はい、ただしクラス自体はありません。 これは明らかですが、1時間前にはありませんでした:-)。 mock.patch.object @ (pyazure、 'PyAzure'、スペック= pyazure.PyAzure) デフtest_management_certificate_connect(自己、mock_pyazure): self.cert1.connect() mock_pyazure.assert_called_with( 'FOO'、 'bar' に) – bfschott

関連する問題