2016-08-30 12 views
0

ビジネスロジックよりもボイラープレートコードで機能するクラスのテストケースを記述しようとしていますが、私は単体テストがこのクラスにとって本当に価値があるかどうか疑問に思っていました。しかし、TDDを使用する場合は、追加するロジックのテストを書くことをお勧めします。明白なユニットテスト

以下の例のように、DIを使用して依存関係を注入し、設定パラメータを取得してアプリケーションの実行を設定します。依存関係が正しく注入されているか、または終了時にdestroy(私のコードよりもJava CDIフレームワークを単体テストする)が呼び出された場合、単体テスト以外に何ができるのでしょうか?

import javax.annotation.PostConstruct; 
import javax.annotation.PreDestroy; 
import javax.ejb.Singleton; 
import javax.ejb.Startup; 
import javax.ejb.TransactionAttribute; 
import javax.ejb.TransactionAttributeType; 
import javax.inject.Inject; 

@Singleton 
@Startup 
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
public class PipsAlprConnectionRunner { 
    @Inject 
    private PipsAlprConfiguration config; 

    @Inject 
    private PipsAlprConnector connector; 

    @Inject 
    private Scheduler scheduler; 

    @Inject 
    @PipsAlprAdapterService 
    private ServiceStatus status; 

    private Timer connectorTimer = null; 

    @PostConstruct 
    public void initialized() { 
     status.started(); 
     connectorTimer = scheduler.schedule(connector, 0, 
       1000 * config.getPollPeriodSeconds()); 
     status.operational(); 
    } 

    @PreDestroy 
    public void destroy() { 
     connectorTimer.cancel(); 
     connector.shutdown(); 
     status.stopped(); 
    } 
} 

私は、上記のクラスで、TDDを利用するために、任意のテストシナリオを考えることができなかったので、単にコードを思い付いた、と今私はまさにここで私のユニットテストすることができ疑問に思って。

答えて

1

まあ、クラスが何かをするケースがあります。それは状態を変え、タイマーを開始します。これらのオブジェクトのモックをMockitoを介してクラスに注入してから、initialized()destroy()の両方がこれらのモックに何をするかを確認してください。

@RunWith(MockitoJUnitRunner.class) 
public class PipsAlprConnectionRunner { 

    @Mock 
    private PipsAlprConfiguration config; 

    @Mock 
    private PipsAlprConnector connector; 

    @Mock 
    private Scheduler scheduler; 

    @Mock 
    private ServiceStatus status;  

    @InjectMocks 
    private PipsAlprConnectionRunner pipsAlprConnectionRunner ; 

    @Test 
    public void initialized_should_set_status_started() { 
     pipsAlprConnectionRunner.initialized(); 
     Mockito.verify(status).started(); 
    } 

    // etc. 
} 

あなたが「失敗のポイント」ごとに1つのメソッドまたは方法/テストにつき一つの方法を作成したい場合にはかなり個人的な好みの問題です。

個人的には、目標は100%のカバレッジだと思うので、主にデリゲートするかなりシンプルなクラスですらカバーする必要があります。誰かが何かを変えたらどうなりますか?このテストでは、このような変更が既存の機能を損なわないことが保証されています。

+0

私はあなたが定義したPipsAlprConnectionRunnerクラスは実際には実際のPipsAlprConnectionRunnerとは異なるテストクラスだと思いますか? DIを介してすべてのオブジェクトが模擬実装で挿入されますか?依存関係が実際に注入されているかどうかをチェックするユニットテストはどうでしょうか?しかし、私は単体テストの実行中にCDIの注入が起こらないので、このようなテストは役に立たないと信じています。 – Saad

+0

いいえ、 'PipsAlprConnectionRunner'は実際にあなたの' PipsAlprConnectionRunner'です。 Mockitoはそれを作成し、擬似depedenciesをそれに注入します。それは '@ InjectMocks'の魔法です。個人的には、DIを自分自身でテストすることはありません。それはフレームワークを効果的にテストするからです。(確かに、正しい注釈があることをテストしています)。とにかくDIに依存する統合テストを後の段階で行うだけで、自動的にテストすることができます。 –

+0

私はありがとう!また、started()メソッドとdestroy()メソッドがPipsAlprConnectionRunnerの内部状態を変更するのは、それをテストする唯一の方法は動作検証と状態検証です。しかし、モックオブジェクトを使ってのみ行うことができます。モックフレームワークを使用していなかったらどうしたらいいでしょうか?あるいは、モックオブジェクトが出現する前に状態を確認することが難しいオブジェクトに対して、単体テストを行う方法はありますか? – Saad

関連する問題