2015-10-26 10 views
7

Pythonは比較的新しい言語です。単体テストと依存関係注入は私が今やっていることです。だから私はC#の観点からそれに精通しています。Pythonで基本的な依存性注入を行う方法(模擬/テスト目的のため)

最近、私はPythonコードのこの作品を書いた:

import requests # my dependency: http://docs.python-requests.org/en/latest/ 

class someClass: 
    def __init__(self): 
     pass 

    def __do(self, url, datagram): 
     return requests.post(self, url, datagram) 

をそして私は、私はちょうどハードコーディングされた依存関係を作成していたことに気づきました。ブリー。私はやって自分のコードを変更すると考えられていた

「コンストラクタ」依存性注入:

def __init__(self,requestLib=requests): 
    self.__request = requestLib 

def __do(self, url, datagram): 
    return self.__request.post(self, url, datagram) 

これは、今、私はユニットテストのために偽/モックの依存性を注入することができますが、この場合は確認されませんでしたPython-icとみなされました。だから私は指導のためにPythonコミュニティに訴求している。

基本的なDI(主にMocks/Fakesを利用する単体テストの作成のため)を行うPythonの方法の例は何ですか? How does @mock.patch know which parameter to use for each mock object?

+2

'__leading_double_underscore'は名前のマングリングを呼び出すので、通常は避けるべきです。テストするモジュールを注入するよりも、 ''要求 ''(https://docs.python.org/3/library/unittest.mock.html)を簡単に取り除くのは簡単でしょうか? – jonrsharpe

+0

私は__leading二重のアンダースコアはメソッドをプライベートにマークすることでした。私は間違っていたのですか?もしそうなら、私はどのようにプライベートな印を付けるべきですか? – Pretzel

+0

モジュールを注入するのではなく、モジュールの要求を模擬する方が簡単でしょうか?知りません。私はPythonのやり方に慣れていないので、私は求めています。 ;) – Pretzel

答えて

5

はそれをしないでください。

モック答えに興味誰のための追補は、私はここに別の質問をすることを決めました。要求を通常どおりにインポートし、通常どおりに使用してください。あなたのコンストラクタに引数としてライブラリを渡すのは面白いことですが、あなたの目的には非常に非平凡で不要です。ユニットテストで物事を模倣するには、模擬ライブラリを使用してください。 python 3ではそれが標準ライブラリに組み込まれています

https://docs.python.org/3.4/library/unittest.mock.html

とPython 2に、あなたは

https://pypi.python.org/pypi/mock

次のようになりますあなたのテストコード(のpython 3を使用して個別にインストールする必要がありますバージョン)

​​
+2

私はあなたのコードを解析しようとしています。 '@patch( "mymodule.requests")は何をしますか?そして、なぜあなたは "要求"を "test_my_code"メソッドに渡していますか?また、 "requests.post"の模様はどのように見えますか? – Pretzel

+1

パッチデコレータは、モックのためにコード内のリクエストモジュールを置き換えます。私のコードは間違っている可能性が高いので、リクエスト内のすべての関数を個別にパッチして動作させる必要があります。パッチされた関数は、引数としてテストに渡されるので、それに対してアサートを行うことができます。その使い方の詳細については、unittestとmockのドキュメントを読んでください。 –

+0

助けてくれてありがとう。私はあなたにチェックマークを付けました。 :) – Pretzel

0

リクエストモジュールを注入するのはあまりにも多すぎるかもしれませんが、非常に良いpですいくつかの依存関係を注射可能なものにすることができます。

本格的なフレームワークが必要な場合があります。そのために、そこにはInjectorのような優れたモジュールがあります。

よりシンプルなアプローチは、デコレータを使って仕事をすることです。そのためのいくつかのモジュールがあります。out there

このようなモジュールは、Injectableの1つで、これはPython 3 @autowiredデコレータを提供し、簡単できれいな依存関係注入を可能にします。

このデコレータの主なポイントは、ということです:関数はすべて

  • 依存関係でオートワイヤリングを意識する必要はありません

    • は怠惰することができ、発信者が明示的に合格することができます
    • を初期化

      01:

    を必要に応じて、依存関係のインスタンスは、基本的には、このようなコードを回しますこの

    def __init__(self, *, model: Model = None, service: Service = None): 
        if model is None: 
         model = Model() 
    
        if service is None: 
         service = Service() 
    
        self.model = model 
        self.service = service 
        # actual code 
    

    @autowired 
    def __init__(self, *, model: Model, service: Service): 
        self.model = model 
        self.service = service 
        # actual code 
    

    複雑なもの、セットアップなし、何のワークフローは強制しません。

  • 関連する問題