2017-01-19 9 views
0

特定の機能をテストするときに複数の検証ステートメントを使用する理由は何ですか?複数の/または依存しないメソッドが呼び出されたことを確認しますか?例についてはユニットテストで複数のベリファイステートメントを使用する価値はありますか?

:最初の文は二wasn呼び出されなかった場合ので、この方法

@Test 
public void testDoSomethingWithSmallSize() throws Exception{ 
    testObj.doSomething(5); 
    verify(someServiceMock, never()).someMethod(); 

    //IS THERE ANY VALUE TO VERFIYING MORE THAN ONE CALL? 
    //LIKE THIS?? 
    verfiy(anotherServiceMock, never()).someMethod(); 
    } 

をテストする

public void doSomething(int size){ 
    if(size < 50){ 
    return; 
    } 
    someService.someMethod(); 
    anotherService.someMethod(); 
} 

が第二の文を確認するか、それが不要である有することに価値がありますどちらか?

+1

"2番目の検証文を持つ価値はありますか?"はい、 'anotherServiceMock.someMethod()'が決して呼び出されなかったことを知りたければ。そうでなければ、いいえ。 –

+0

@Andy Turnerしかし、最初のものが呼び出されなかったなら、それは必要か、それとも呼び出されなかったと思いますか? – Rosie

+3

@Rosieもし自分のメソッドが自分の考えていることをやっていると仮定しようとするなら、何もテストする必要はありません。 – khelwood

答えて

1

コードが変更される可能性があるため、2つのステートメントを確認する必要があります。

ユニットテストは、コードのドキュメントのいくつかの種類です。

  • 両方のステートメントを確認することは、両方のステートメントを呼び出さなければならないことを意味します。
  • 1つのみを検証することは、第1ステートメントだけを呼び出さなければならないことを意味します。

誰かがif文の中anotherService.someMethod()を呼び出す方法を変更した場合、テストはまだ検証1で通過し、検証2で失敗します。

0

はい!単体テストの機能の一部は、コードの予想される動作を文書化することです。テストは、テスト中のコードをブラックボックスとして扱う方法で記述する必要があります。テスト中のコードが特定の順序で2つのことを行う場合(条件が満たされた場合)、単体テストはすべてのことが正の条件で行われ、項目のうちのいずれも負の条件で行われていないことを確認する必要があります。

あなたのテストで1つの条件だけをチェックしてから2年後に、インターンがコードを更新し、チェックされている1つのタスクを削除する必要があります。あなたのテストは引き続き実行されます(コードは削除されていません - チェック!)が、コードが正しく動作しているとは限りません。

1

あなたのテストは、一度に1つの "概念"をテストするだけで、 "あまりにも多くの"テストを構成するものは何かについての判断の問題であると心配するのは当然です。あなたの元の例は良いものです:

@Test 
public void testDoSomethingWithSmallSize() throws Exception{ 
    testObj.doSomething(5); 
    verify(someServiceMock, never()).someMethod(); 
    verify(anotherServiceMock, never()).someMethod(); 
    // GOOD: You've called one method-under-test and 
    // verified two related postconditions. A perfect, small, clear test. 
} 

しかしこれはあまりにも遠すぎます。

@Test 
public void testDoSomethingWithAnySmallSize() throws Exception{ 
    testObj.doSomething(1); 
    testObj.doSomething(3); 
    testObj.doSomething(5); 
    verify(someServiceMock, never()).someMethod(); 
    verify(anotherServiceMock, never()).someMethod(); 
    // LESS GOOD: You've called one method-under-test three times, but 
    // they share postconditions and concepts. Pragmatic, but not the 
    // "one test method for one test case" ideal of most frameworks. 
} 

@Test 
public void thisShouldBeThreeTests() throws Exception{ 
    testObj.doSomething(7); 
    verify(someServiceMock).doAThing(7); 
    verify(anotherService).doAThing(700); 

    testObj.doSomethingElse(9); 
    verify(someServiceMock).doAThing(9); 
    verify(anotherService).doAThing(900); 

    testObj.doAThirdThing(12); 
    verify(someServiceMock).doAThing(12); 
    verify(anotherService).doAThing(1200); 

    // BAD: Even though these are related, this could easily be three 
    // unrelated tests for better naming and reporting, and to help you 
    // identify why one case might be failing versus three. Break this up. 
} 

そうです、同じテストで複数のverifyを持っていることを恐れてはいけませんが、再設定している場合は、あなたのverify文は無関係であることを脱線させないように気をつけて、特に注意が必要ですMockitoのresetメソッドによるテスト設定。

関連する問題