簡體   English   中英

如何在使用Mockito和JUnit的方法中檢查if語句?

[英]How to check if-statement in method using Mockito and JUnit?

我有應該測試的方法。 代碼(當然,某些部分被剪切):

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語句是否正常工作。

如果您真的希望單元測試而不是集成測試,則可以依靠注釋@Mock來模擬服務FilterDataProvider並使用@InjectMocks來將模擬注入到FilterDataController實例中。

然后,您可以提出3個測試:

  1. 日期正確無誤的一項測試,
  2. 日期正確但相等的另一個日期
  3. 最后一個日期不正確的對象將拋出ValueNotAllowedException ,可以使用@Test(expected = ValueNotAllowedException.class)對其進行開箱測試。

如果需要確保已使用期望的參數調用filterDataProvider.getPossibleCountries(startDate, newEndDate) ,則需要使用verify

該代碼將是這樣的:

@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
    }
}

您將必須模擬FilterDataProvider ,然后使用InjectMocks將其注入到測試類中。

getPossibleFilterData將是被測試的方法,因此請選擇任何特定日期(使用Calendar.set(...) ,然后選擇Calendar.getTime() ),並將相同的日期作為startDate和endDate發送。

現在,在完成getPossibleFilterData之后,您可以驗證是否以結束日期(比開始日期多一毫秒)調用filterDataProvider.getPossibleCountries 這可以通過模擬類的方法內的Calendar.getTimeInMillis()來完成,也可以通過使用Mockito進行驗證,該Date的日期比最初指定的日期大一毫秒。

編輯:提供的代碼示例:

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));
    }
}

我看到兩種主要方法。

  1. 使用Mockito功能:如果為控制器注入模擬FilterDataProvider(這是標准方法,例如使用MockitoJUnitRunner和@InjectMocks),則可以使用Mockito的“ verity”選項來確保其具有正確的endDate。 參見討論: http : //www.vogella.com/tutorials/Mockito/article.html#mockito_verify
  2. 顯然,還有其他方法依賴邏輯而不是技術。 例如:將“ if”部分重構為單獨的方法“ correctEndDate”,或填充數據,以便根據endDate返回不同​​的coutries列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM