0

非常にうまく設計されていると思われるコードを書いたことがありますが、そのコードの単体テストを書き始めて、確信が持てなくなってしまいました。

合理的な単体テストを作成するには、変数アクセス修飾子の一部を から に変更する必要があることがわかりましprivatedefault。つまり、それらを公開します (パッケージ内のみですが、それでも...)。

問題のコードの大まかな概要を次に示します。何らかの外部 Web サービスや DB 内のデータ、またはその他のソースによってアドレスを検証するなど、さまざまな手段でアドレス検証を可能にする、ある種のアドレス検証フレームワークがあるはずです。つまりModule、アドレスを検証するための別の方法です。私はインターフェースを持っています:

interface Module {

  public void init(InitParams params);

  public ValidationResponse validate(Address address);
}

リクエストまたはセッション状態に基づいて適切なモジュールを選択する、ある種のファクトリがあります。

class ModuleFactory {

  Module selectModule(HttpRequest request) {
       Module module = chooseModule(request);// analyze request and choose a module
       module.init(createInitParams(request)); // init module
       return module;
  }

}

そして、Module検証のためにいくつかの外部 Web サービスを使用する を作成し、そのように実装しました。

WebServiceModule {
   private WebServiceFacade webservice;     

   public void init(InitParams params) {
      webservice = new WebServiceFacade(createParamsForFacade(params));
   }

   public ValidationResponse validate(Address address) {
      WebService wsResponse = webservice.validate(address);
      ValidationResponse reponse = proccessWsResponse(wsResponse);
      return response;
   }

}

したがって、基本的にはこれWebServiceFacadeが外部 Web サービスのラッパーであり、モジュールがこのファサードを呼び出し、その応答を処理し、フレームワーク標準の応答を返します。

WebServiceModuleプロセスが外部 Web サービスから正しく応答するかどうかをテストしたいと考えています。明らかに、単体テストで実際の Web サービスを呼び出すことはできないため、モックを作成しています。しかし、モジュールがモックされた Web サービスを使用するにはwebservice、外部からフィールドにアクセスできる必要があります。それは私のデザインを壊し、それについて何かできることはないかと考えています. 明らかに、ファサードは init パラメーターで渡すことができませんModuleFactory

依存性注入がそのような問題の解決策になる可能性があると読みましたが、その方法がわかりませんか? Guiceなどの DI フレームワークを使用したことがないため、この状況で簡単に使用できるかどうかはわかりません。しかし、多分それはできますか?

それとも、デザインを変更する必要がありますか?

それとも、この不運なフィールド パッケージを非公開に// default visibility to allow testing (oh well...)ますか?

ばっ!これを書いているときに、コンストラクターの引数としてWebServiceProcessorを受け取る を作成し、 . これは私の問題に対する解決策の1つです。あなたはそれについてどう思いますか?これには 1 つの問題があります。その場合、すべての作業を別のコンポーネントに委譲するだけで、役に立たなくなるからです。WebServiceFacadeWebServiceProcessorWebServiceModule

4

2 に答える 2

2

はい、あなたのデザインは間違っています。クラス内ではなく、依存性注入を行う必要がnew ...あります (「ハードコーディングされた依存性」とも呼ばれます)。テストを簡単に書けないことは、設計が間違っていることを完全に示しています (「テストに導かれたオブジェクト指向ソフトウェアの成長」の「テストに耳を傾ける」パラダイムについて読んでください)。

ところで、 PowerMockのようなリフレクションまたは依存関係を破るフレームワークを使用することは、この場合非常に悪い習慣であり、最後の手段にする必要があります。

于 2013-10-11T10:41:20.967 に答える