3

TDDの範囲でリファクタリングを明確にしたい。

前:

class Somclass{
      public void sendMessage(){    
       WebServiceStub stub = new WebServiceStub();     
      ...
      stub.sendMsg();        
      }
    }

後:

class Somclass{
private WebServiceStub stub;

  public void sendMessage(){
    ...
  if(stub == null){
   stub = new WebServiceStub();
  }
  ...
  stub.sendMsg();        
  }
}

だから私は sendMsg() メソッドを検証し、結果でいくつかのアサートを行いたい. このスタブをモックできるようにするために、このスタブ ローカル変数をインスタンス変数に移動します。モックされたスタブをクラスに設定し、テスト クラスで検証とアサートを実行できるようにします。例えば:

@Test
public void testSMth(){
  wsProvider.setStub(stubMock);
  verify(stubMock).sendMsg();
  ...asserts
}

このアプローチはスレッド セーフではないため、並行性の変更を行う必要があります。この変更により、エラーが発生する可能性があります。したがって、ローカル変数 approce にはスレッドセーフがあります。

また、WebServiceStub のインスタンスを返す Factory を作成することもできます。ただし、このような状況は頻繁に発生するため、このアプローチでは新しいクラスが生成されます。

質問があります: このケースをどのようにテストし、goot テストは間違いを引き起こす可能性のある変更にコストがかかりますか?

4

3 に答える 3

4

WebServiceクラスには、フィールドとしてオブジェクト(「スタブ」とは呼びません)が必要です。

class Someclass{

  @Resource
  private WebService ws;

  public void sendMessage(){

  ws.sendMsg();        
  }
}

選択したDIフレームワークを注入する必要があります。テストでは、モックに設定できます。あなたの指摘はスレッドセーフではないので、怠惰なゲッターは必要ありません。

于 2012-04-27T09:53:32.487 に答える
3

コンストラクター注入を使用して、依存関係が設定されていない可能性を回避します。これにより、テストでモックを簡単に使用できるようになります。

WebServiceStubクラスが実際にスレッドセーフでない場合 (ただし、JAX WebServiceStub-WS によって生成された場合、metro/jax-ws スタブは多くの場合スレッドセーフであることを知っておく必要があります)、はい、ファクトリを使用する必要があります。これは大したことではなく、それほど遅くなることはありません。必要に応じて、静的内部クラスを使用できます。

于 2012-04-27T10:32:37.803 に答える
0

ほとんど正しいように見えますが、stub == Null の場合、スタブをインスタンス化することはありません。代わりに、ArgumentNullException が発生します。Null は有効な引数として受け入れられるべきではありません (本当に、本当に、本当に正当な理由がない限り)。

于 2012-04-27T09:54:49.360 に答える