В моем тестовом примере мне нужен метод, чувствительный к времени тестирования, в этом методе мы используем java 8 class LocalDate, он не Joda.
Что я могу сделать, чтобы изменить время, когда я запускаю проверку
В моем тестовом примере мне нужен метод, чувствительный к времени тестирования, в этом методе мы используем java 8 class LocalDate, он не Joda.
Что я могу сделать, чтобы изменить время, когда я запускаю проверку
В вашем коде замените LocalDate.now()
на LocalDate.now(clock);
,
Затем вы можете передать Clock.systemDefaultZone()
для производства и фиксированные часы для тестирования.
Это пример:
Сначала введите Clock
. Если вы используете весеннюю загрузку, просто выполните:
@Bean
public Clock clock() {
return Clock.systemDefaultZone();
}
Во-вторых, вызовите LocalDate.now(clock)
в вашем коде:
@Component
public class SomeClass{
@Autowired
private Clock clock;
public LocalDate someMethod(){
return LocalDate.now(clock);
}
}
Теперь внутри вашего класса юнит-теста:
// Some fixed date to make your tests
private final static LocalDate LOCAL_DATE = LocalDate.of(1989, 01, 13);
// mock your tested class
@InjectMocks
private SomeClass someClass;
//Mock your clock bean
@Mock
private Clock clock;
//field that will contain the fixed clock
private Clock fixedClock;
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
//tell your tests to return the specified LOCAL_DATE when calling LocalDate.now(clock)
fixedClock = Clock.fixed(LOCAL_DATE.atStartOfDay(ZoneId.systemDefault()).toInstant(), ZoneId.systemDefault());
doReturn(fixedClock.instant()).when(clock).instant();
doReturn(fixedClock.getZone()).when(clock).getZone();
}
@Test
public void testSomeMethod(){
// call the method to test
LocalDate returnedLocalDate = someClass.someMethod();
//assert
assertEquals(LOCAL_DATE, returnedLocalDate);
}
Вы можете реорганизовать свой код, чтобы сделать его удобным для тестирования, например, заменить все вызовы LocalDate.now()
на вызов некоторого метода пользовательского макетируемого нестатического класса.
В качестве альтернативы вы можете использовать PowerMock mockStatic.
Вы также можете передать фиксированные часы в производстве (значение которых фиксировано в начале транзакции), чтобы избежать использования непоследовательных "сейчас" в разных сущностях и запросах. Подробнее см. этот вопрос.
Если нам нужно смоделировать статические методы, такие как now(), мы можем использовать несколько альтернатив, таких как PowerMock:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ LocalDateTime.class })
public class LocalDateTimeUnitTest {
@Test
public void givenLocalDateTimeMock_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
LocalDateTime dateTime = LocalDateTime.now(clock);
mockStatic(LocalDateTime.class);
when(LocalDateTime.now()).thenReturn(dateTime);
String dateTimeExpected = "2014-12-22T10:15:30";
LocalDateTime now = LocalDateTime.now();
assertThat(now).isEqualTo(dateTimeExpected);
}
}
Или JMockit, действительно, с JMockit мы можем использовать класс MockUp:
@Test
public void givenLocalDateTimeWithJMock_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-21T10:15:30.00Z"), ZoneId.of("UTC"));
new MockUp<LocalDateTime>() {
@Mock
public LocalDateTime now() {
return LocalDateTime.now(clock);
}
};
String dateTimeExpected = "2014-12-21T10:15:30";
LocalDateTime now = LocalDateTime.now();
assertThat(now).isEqualTo(dateTimeExpected);
}
Или класс Ожидания:
@Test
public void givenLocalDateTimeWithExpectations_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-23T10:15:30.00Z"), ZoneId.of("UTC"));
LocalDateTime dateTimeExpected = LocalDateTime.now(clock);
new Expectations(LocalDateTime.class) {
{
LocalDateTime.now();
result = dateTimeExpected;
}
};
LocalDateTime now = LocalDateTime.now();
assertThat(now).isEqualTo(dateTimeExpected);
}
Мы можем найти больше примеров здесь.
Другой простой альтернативой является использование метода now() с фиксированным экземпляром Clock. Конечно, большинство классов в пакете java.time имеют метод now() с параметром Clock:
@Test
public void givenFixedClock_whenNow_thenGetFixedLocalDateTime() {
Clock clock = Clock.fixed(Instant.parse("2014-12-22T10:15:30.00Z"), ZoneId.of("UTC"));
String dateTimeExpected = "2014-12-22T10:15:30";
LocalDateTime dateTime = LocalDateTime.now(clock);
assertThat(dateTime).isEqualTo(dateTimeExpected);
}