2016-10-11 51 views
1

私はテストするべき方法があります。コード(もちろん、いくつかの部分がカットされた):MockitoとJUnitを使ってif文をチェックする方法は?

public class FilterDataController { 

    public static final String DATE_FORMAT = "yyyy-MM-dd"; 

    @Autowired 
    private FilterDataProvider filterDataProvider; 

    @ApiOperation(value = "Get possible filter data",response = ResponseEntity.class) 
    @ApiResponses(value = { 
      @ApiResponse(...), 
      @ApiResponse(...)}) 
    @RequestMapping(path = "...", method = RequestMethod.GET) 
    public ResponseEntity<Object> getPossibleFilterData(
      @RequestParam(value = "startDate") @DateTimeFormat(pattern=DATE_FORMAT) final Date startDate, 
      @RequestParam(value = "endDate") @DateTimeFormat(pattern=DATE_FORMAT) final Date endDate) { 
     if (endDate.compareTo(startDate) == -1){ 
      throw new ValueNotAllowedException("End date should be after or equal start date"); 
     } 
     else { 
      Date newEndDate = endDate; 
      if (startDate.equals(endDate)){ 
       newEndDate = new Date(endDate.getTime() + TimeUnit.DAYS.toMillis(1) - 1); 
      } 

      List<String> possibleCountries = Lists.newArrayList(filterDataProvider.getPossibleCountries(startDate, newEndDate)); 

      return new ResponseEntity<>(new FilterResponse(possibleCountries),HttpStatus.OK); 
     } 
    } 
} 

質問:MockitoとJUnitを用いた方法getPossibleFilterDataにif文をチェックするにはどのように?メソッドに等しい日付を渡して、if文が正しく機能することを確認します。

+1

以下の答えの多くで述べたように、テストでは実装を想定すべきではありません。メソッドをリファクタリングして正しい値を返すようにしたら、if文はまったく使用しませんか?それを仮定するのではなく、間違った値で_passを実行し、正しいexception_をキャッチしたときにのみテストをパスします。 –

+0

@JeffBowmanアドバイスありがとうございます。コードのおかげで – Woland

答えて

2

あなたが本当に純粋ユニットテストではない統合テストをしたい場合は、あなたがFilterDataControllerのインスタンスにあなたのモックを注入するために、あなたのサービスFilterDataProvider@InjectMocksを模擬するために、注釈@Mockに頼ることができます。

次にあなたが提案する可能性が3つのテスト:日付は補正するが、異なっている

  1. 一つのテスト、
  2. 別の日付は補正するある1が、同じ
  3. そして最後に1日付が間違っていて、@Test(expected = ValueNotAllowedException.class)を使用して箱からテストできるValueNotAllowedExceptionが投げられます。

filterDataProvider.getPossibleCountries(startDate, newEndDate)が期待される引数で呼び出されていることを確認する必要がある場合は、verifyを使用する必要があります。

コードは、そのようなものになるだろう:あなたはFilterDataProviderを模擬して、InjectMocksを使用して、テストクラスにこれを注入する必要があります

@RunWith(MockitoJUnitRunner.class) 
public class FilterDataControllerTest { 
    @Mock 
    FilterDataProvider filterDataProvider; 
    @InjectMocks 
    FilterDataController controller; 

    @Test(expected = ValueNotAllowedException.class) 
    public void testGetPossibleFilterDataIncorrectDates() { 
     controller.getPossibleFilterData(new Date(1L), new Date(0L)); 
    } 

    @Test 
    public void testGetPossibleFilterDataCorrectDates() { 
     // Make the mock returns a list of fake possibilities 
     Mockito.when(
      filterDataProvider.getPossibleCountries(
       Mockito.anyObject(), Mockito.anyObject() 
      ) 
     ).thenReturn(Arrays.asList("foo", "bar")); 
     ResponseEntity<Object> response = controller.getPossibleFilterData(
      new Date(0L), new Date(1L) 
     ); 
     Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); 
     // Make sure that 
     // filterDataProvider.getPossibleCountries(new Date(0L), new Date(1L)) 
     // has been called as expected 
     Mockito.verify(filterDataProvider).getPossibleCountries(
      new Date(0L), new Date(1L) 
     ); 
     // Test response.getBody() here 
    } 

    @Test 
    public void testGetPossibleFilterDataEqualDates() { 
     // Make the mock returns a list of fake possibilities 
     Mockito.when(
      filterDataProvider.getPossibleCountries(
       Mockito.anyObject(), Mockito.anyObject() 
      ) 
     ).thenReturn(Arrays.asList("foo", "bar")); 
     // Call the controller with the same dates 
     ResponseEntity<Object> response = controller.getPossibleFilterData(
      new Date(1L), new Date(1L) 
     ); 
     Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); 
     Mockito.verify(filterDataProvider).getPossibleCountries(
      new Date(1L), new Date(TimeUnit.DAYS.toMillis(1)) 
     ); 
     // Test response.getBody() here 
    } 
} 
+0

ありがとうございます。しかし、 'filterDataProvider'が正しい日付で呼び出されたことを確認する方法はありますか? 'getPossibleFilterData'に等しい日付を送り、' filterDataProvider.getPossibleCountries(startDate、newEndDate) 'が修正された日付で呼び出されたことを確認します。 – Woland

1

getPossibleFilterDataはテスト中のメソッドになりますので、特定の日付(Calendar.set(...)、次にCalendar.getTime())を選択し、startDateとendDateの両方と同じ日付を送信します。

getPossibleFilterDataが完了した後、filterDataProvider.getPossibleCountriesが開始日よりも1ミリ秒後の終了日で呼び出されたかどうかを確認できます。これは、嘲笑されたクラスのメソッド内のCalendar.getTimeInMillis()によって、または最初に指定された日付よりも1ミリ秒以上長い日付でMockitoで検証することによって行うことができます。

編集:コード例提供:

public class FilterDataControllerTest { 
    @Test 
    public void testSameDate() { 
     FilterDataProvider provider = Mockito.mock(FilterDataProvider.class); 
     FilterDataController controller = new FilterDataController(provider); 

     Date startDate = new GregorianCalendar(2016, Calendar.JANUARY, 11).getTime(); 
     Date endDate = new GregorianCalendar(2016, Calendar.JANUARY, 11).getTime(); 
     Date expectedEndDate = new Date(endDate.getTime() + TimeUnit.DAYS.toMillis(1) - 1); 

     controller.getPossibleFilterData(startDate, endDate); 

     Mockito.verify(provider).getPossibleCountries(Mockito.eq(startDate), Mockito.eq(expectedEndDate)); 
    } 
} 
+0

"またはMockitoと確認することによって" - あなたはそれを行う方法を説明できますか?私の元々の質問は、endDate == startDateの場合に** endDateが**変更されたことを確認する方法です。このような場合は内部のif文に相当します。 – Woland

+0

@Woland Iveはあなたのコードサンプルを追加しました – mdewit

+0

あなたのコードは 'FilterDataController'のコンストラクタを書く必要がありますが、私の状況ではそれは不公平です。私はそれを覚えています。 +1 – Woland

0

私は2つの主要なアプローチを参照してください。 Mockitoの機能を使用して

  1. :あなたは(例MockitoJUnitRunnerと@InjectMocksのために使用して、標準的なアプローチである)モックFilterDataProviderを使用してコントローラを注入した場合は、必ずそれを持って作るMockitoの「真実」オプションを使用することができます正しいendDate。論議を参照してください:http://www.vogella.com/tutorials/Mockito/article.html#mockito_verify
  2. 明らかに、技術よりもロジックに依存する他のアプローチがあります。たとえば、 "if"部分をseparateMethod "correctEndDate"にリファクタリングするか、endDateに基づいて別のcoutriesのリストが返されるようにデータを入力します。
+0

ありがとうございます。 'verify(test).testing(Matchers.eq(12));'の例があります。しかし私の場合、私のメソッドのメソッドが修正された日付で呼び出されたことを確認したい。たぶん、そのようなスマート 'newEndDate = ...; (FilterDataController).getPossibleFilterData()。getPossibleCountries(Matchers.eq(startDate、newEndDate)); ' – Woland

関連する問題