如何使用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 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 possibleCountries = Lists.newArrayList(filterDataProvider.getPossibleCountries(startDate, newEndDate)); return new ResponseEntity(new FilterResponse(possibleCountries),HttpStatus.OK); } } } 

问题:如何使用Mockito和JUnit检查方法getPossibleFilterData if语句? 我希望将方法传递给方法,然后检查我的if语句是否正常工作。

如果你真的想要一个unit testing而不是集成测试,你可以依靠注释@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 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 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完成之后,您可以validation是否调用了filterDataProvider.getPossibleCountries ,其结束日期比开始日期多一毫秒。 这可以通过模拟类的方法中的Calendar.getTimeInMillis()来完成,或者通过使用比最初指定的日期多一毫秒的日期validationMockito来完成。

编辑:提供的代码示例:

 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. 使用Mockitofunction:如果您使用模拟FilterDataProvider注入控制器(这是标准方法,使用例如MockitoJUnitRunner和@InjectMocks),那么您可以使用Mockito的“verity”选项来确保它获得正确的endDate。 请参阅讨论: http : //www.vogella.com/tutorials/Mockito/article.html#mockito_verify
  2. 显然,还有其他方法依赖于逻辑而不是技术性。 例如:将“if”部分重构为separateMethod“correctEndDate”,或者填充数据,以便根据endDate返回不同​​的coutries列表。