2016-12-16 23 views
0

シングルトンパターンに従うクラスは次のようにします。 Pythonモジュールautomaton.pyでは私が持っている:私は、他のモジュールの様々な中からオブジェクトのメソッドを呼び出していますPythonでテスト可能なシングルトンを作成する最適な方法

class Automaton(object): 
    def launch_probe(self): 
     if hasattr(self, 'launched') and self.launched: 
      return 
     print "Launched!" 
     self.launched = True 

automaton = Automaton() 

。どこにも私は、クラスをインスタンス化し、私はそれがこのような単純な、それへのアクセスを維持するために良いことですので、多くの場合、プロパティのメソッドを呼び出すか、アクセスされることを期待します:

from automaton import automaton 

automaton.launch_probe() 
print 'Status:' 
print automaton.launched 

しかし、今、私はより良いテストにこのコードを作業し、希望していますsetUp()の単体テスト間でシングルトンをリセットしたい。

import automaton 

def setUp(): 
    automaton.automaton = automaton.Automaton() 

しかし、これは、他のロードされたモジュールが元のシングルトンへの参照を持っているため、ジョブは完了しません。私はAutomaton.get_instance()でシングルトンを取得するか、モジュールをインポートしてそのモジュール内の変数を参照するパターンに切り替えることができますが、これにより、メインのプロダクションコードをより冗長でより厳密にすることができます。私はautomaton変数を記述子にしてインテリジェンスを持たせることを検討していましたが、記述子はクラス内でしか動作しないことを発見しました。私が検討していた最終的なアプローチは、辞書をクリアして__init__というメソッドを呼び出すことによって、Automatonの既存のインスタンスを再初期化しようとしたところでした。このようなもののために推奨されるアプローチは何ですか?

+0

可能な解決策の多くと多分1推奨だけでなく、アプローチがあります。 (私見では)。クリーンスタートアップを保証する 'プライベート' _reset()メソッドを追加します(特にテストで必要な場合はどこでも)。しかし、本当にクラスが必要ですか?あなたのシングルトンは単なるオートメーションモジュールそのもの(オブジェクトである)かもしれませんし、関数を定義しているかもしれません... –

+0

クラスを使用する利点は、すべての状態がそのインスタンスの '__dict__'に埋められているので、リセットするのがさらに簡単です'__name__'のような他のフィールドと、残す必要がある関数やその他のコードを含むグローバルなモジュール空間よりもテストするためのものです。 – penguin359

答えて

0

多くの利用可能なオプションの一つは、例えば、状態ゼロ(初期状態)にシングルトンをリセットする方法を提供していることになる。

class Automaton(object): 

    def __init__(self): 
     self.reset() 

    def reset(self): 
     self.launched = False 

    def launch_probe(self): 
     if hasattr(self, 'launched') and self.launched: 
      return 
     print("Launched!") 
     self.launched = True 

automaton = Automaton() 

if __name__ == "__main__": 
    import unittest 

    class Test(unittest.TestCase): 

     def setUp(self): 
      automaton.reset() 

     def test1(self): 
      automaton.launch_probe() 
      self.assertEqual(automaton.launched, True) 

     def test2(self): 
      self.assertEqual(automaton.launched, False) 

    unittest.main() 
関連する問題