У меня есть метод, который я должен проверить. Код (конечно, некоторые части были разрезаны):
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);
}
}
}
Вопрос: как проверить if-statement в методе getPossibleFilterData
с помощью Mockito и JUnit? Я хочу передать равные даты методу, а затем проверить, что мой if-statement работает правильно.
Если вы действительно хотите, чтобы чистый unit тест не был интеграционным тестом, вы можете положиться на аннотацию @Mock
чтобы @Mock
вашу службу FilterDataProvider
и @InjectMocks
чтобы @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<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
был вызван с правильными датами? Я хочу отправить getPossibleFilterData
равные даты, а затем проверить, что filterDataProvider.getPossibleCountries(startDate, newEndDate)
с исправленными датами.
Вам придется издеваться над FilterDataProvider
а затем ввести это в свой тестовый класс с помощью InjectMocks.
getPossibleFilterData
будет тестируемым методом, поэтому выберите любую конкретную дату (используйте Calendar.set(...)
, затем Calendar.getTime()
) и отправьте ту же дату, что и startDate и endDate.
Теперь, после завершения getPossibleFilterData
, вы можете проверить, был ли filterDataProvider.getPossibleCountries
с конечной датой, которая на миллисекунду больше даты начала. Это можно сделать через Calendar.getTimeInMillis()
внутри метода изделенного класса или путем проверки с помощью 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));
}
}
Я вижу два основных подхода.
verify
. Есть пример verify(test).testing(Matchers.eq(12));
, Но в моем случае я хочу проверить, что метод в моем методе был вызван с исправленными датами. Может быть, что-то вроде этого newEndDate = ...; verify(FilterDataController).getPossibleFilterData().getPossibleCountries(Matchers.eq(startDate, newEndDate));
if
? Вместо того чтобы предполагать это, передайте ошибочные значения и проходите тест только тогда, когда вы поймаете правильное исключение .