2

テストを書いていて、特定のメソッドにモックを渡す必要がありました。コンストラクターを介して、または問題のメソッドに直接渡すことの利点はあるのでしょうか。それとも、それは本当に問題ではありません。

例えば

コンストラクターを介してインターフェイス/モックを渡す

class User()
{
  IClock clock;

  User(IClock clock) {this.clock = clock;}

  User GetUser(){ ..}
  UpdateUser(User user) {
     ... 
     this.clock.Now();
     ...
  }
}

インターフェイス/モックをメソッドに渡す

class User()
{
  User GetUser(){ ..}
  UpdateUser(IClock clock, User user) {
     ... 
     clock.Now();
     ...
  }
}

ありがとう!

編集

この場合、IClock は DateTime をラップします。テスト容易性のためにこれを行います。事実上、IClock 自体を構築するオーバーライドを用意します。

例えば。メソッドの場合:

UpdateUser(User user) {
  UpdateUser(new Clock(), user);
}

Clock は DateTime をカプセル化します。

4

3 に答える 3

3

この場合の IClock は非表示のシングルトンです。基盤となるオペレーティング システムから現在の日時を生成します。信頼できる受け入れテストを作成する場合は、それらのテストで日時プロバイダーをスタブ化する必要があります。

このため、この依存関係をモジュールの境界まで公開し、共通の日時ソースをモジュール (およびシステム全体) に注入する必要があります。受け入れテストを作成するときに、この「IClock」日時ソースをスタブすることがあります。

これにより、次のような質問に答えることができます。

  • 私のシステムはうるう日に動作しますか?
  • 私のシステムは真夜中に作動しますか?
  • 私のシステムは大晦日に動作しますか?

コンストラクターの署名またはメソッドの署名のいずれかに IClock 依存関係があると、メソッドまたはオブジェクトが日時に依存していることをユーザーに明確に文書化できます。日時への依存は、通常、オブジェクトの動作を理解しようとするときに非常に重要であるため、強調する必要があります。通常、この依存関係を隠すもの (オーバーロードされたメソッド定義でデフォルトの日時ソースを提供するなど) は避けてください。これにより、上記で説明したような受け入れテストを作成できなくなります。

依存関係をコンストラクターに渡すかメソッドに渡すかの選択は、通常、システムの残りの部分に対するメソッドの責任に依存します。メソッドは、オブジェクトが実行中のシステム内のピアと通信するために使用するパブリック プロトコルを形成しますが、コンストラクター パラメーターは、この特定の実装がその役割を果たすために必要な依存関係です。

次の質問を自問してください。

  • このメソッドの責任は、必ずしも日時の知識を伴いますか?
  • それとも、この特定のオブジェクトのメソッドの特定の実装と関係があるのでしょうか?それは、日時が必要であることを意味しますか?
  • メソッドの呼び出し元が、このオブジェクトの日付/時間のビューを操作する責任を負うのは合理的でしょうか?それともモジュール構成の責任ですか?
  • このオブジェクトを同じインターフェイスの別の実装と交換した場合、その実装がこのメソッドの日時を必要としないというのは合理的でしょうか?
  • 日時を必要とするオブジェクトのメソッドはいくつありますか? 日時の同じビューが必要ですか?
于 2012-07-19T10:27:25.873 に答える
1

依存関係 (つまりIClock) をコンストラクターに渡すこと、つまりコンストラクター インジェクションは、通常、これが特定のクラスのオブジェクト全体に必要な依存関係であることを意味します。クラスのメソッドに依存関係を渡す、つまりメソッド注入により、この特定のメソッドだけが依存するようになります。他にも 2 つの可能性があります。プロパティへの依存関係の注入 (プロパティ インジェクション、つまり、クラスのオブジェクトに対するオプションの依存関係) と、めったに使用されないアンビエント コンテキストです。

したがって、これは、チーム内のコード スタイルの好み、設計、および合意の問題です。

あなたの例では、IClockオブジェクトの依存関係は必要ないUserため、メソッド注入がより適切です。

于 2012-07-19T09:28:46.260 に答える
1

それは、誰が知っているかによって異なりIClockます。UserUpdateUser

コンストラクターに渡すと、Userオブジェクトを渡すことができ、誰でも を呼び出すことができますUpdateUserが、 を介して渡すとUpdateUser、そのメソッドを使用する人は誰でもIClock参照を保持する必要があります。

于 2012-07-19T09:19:09.707 に答える