如何使用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个测试:
- 一个测试,其中日期是纠正但不同,
- 另一个日期更正但相等的
- 而日期不正确的最后一个将抛出一个
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
您将不得不模拟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)); } }
我看到两种主要方法。
- 使用Mockitofunction:如果您使用模拟FilterDataProvider注入控制器(这是标准方法,使用例如MockitoJUnitRunner和@InjectMocks),那么您可以使用Mockito的“verity”选项来确保它获得正确的endDate。 请参阅讨论: http : //www.vogella.com/tutorials/Mockito/article.html#mockito_verify
- 显然,还有其他方法依赖于逻辑而不是技术性。 例如:将“if”部分重构为separateMethod“correctEndDate”,或者填充数据,以便根据endDate返回不同的coutries列表。