2012-04-27 9 views
3

TDDの範囲でリファクタリングを明確にしたいと思います。前「きれいな」JUnitテストを書くためのリファクタリング

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テストのコスト変更ですか?

+1

生成されたWebServiceクラスを参照するには、「スタブ」を使用して自分自身と他のすべての人を混乱させることができます。私はこれが頻繁に使用されていることを知っていますが、単体テストの文脈では、「スタブ」はまったく異なるものを意味します。 – artbristol

答えて

4

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

class Someclass{ 

    @Resource 
    private WebService ws; 

    public void sendMessage(){ 

    ws.sendMsg();   
    } 
} 

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

+0

私のDIフレームワーク(ATG Dynamo)クラスには、セッターとゲッターが必要です。 – Oleksandr

+0

out setterを使用していない場合、テストで変数を設定する可能性はありません。 – Oleksandr

+0

セッターに入れて:-) – artbristol

0

stub == Nullの場合はほぼ正しいようですが、スタブをインスタンス化しないでください。代わりに、ArgumentNullException。あなたが本当に本当に本当に良い理由がない限り、Nullは決して有効な議論として受け入れるべきではありません。

+0

私は明確でない場合は申し訳ありません。 "本当の"ケースのif()ステートメントです。スタブは、テストクラスではなく、毎回コードのnullをnullになります。しかし、wsスタブに関するアドバイスをいただきありがとうございます。 – Oleksandr

3

constructor injectionを使用すると、依存関係が設定されていない可能性があります。これにより、テストでモックを簡単に使用することができます。

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