Mocking DateFormat, SimpleDateFormat, Класс даты - PullRequest
0 голосов
/ 30 апреля 2019

Мне нужно смоделировать требуемый класс (ы) и получить желаемый результат даты.

Я уже пытался смоделировать функцию format () в классе DateFormat, но не сработал.

class XYZ {

   private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
   private static final TimeZone UTC = TimeZone.getTimeZone("UTC");

   public void buildStr(StringBuilder str){
     DATE_FORMAT.setTimeZone(UTC);
     Date date = getDate();
     str.append(DATE_FORMAT.format(date));
   }

   private Date getDate(){
     return new Date();
   }

}

В этом коде я ожидаю, что к звезде будет добавлено "20190430000000" (именно это значение), но я получаю текущее время UTC.

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

java.time

Вы используете ужасные классы даты и времени, которые были вытеснены несколько лет назад современными java.time классами, определенными в JSR 310.

Clock

Классы java.time принимают необязательный аргумент Clock.Передайте объект Clock с поведением, необходимым для вашего теста.Класс Clock имеет статические методы, обеспечивающие несколько специальных поведений.К ним относятся фиксированный момент, скользящий момент, установленный на определенное количество времени впереди или позади истинных часов, и измененная частота, например, увеличение на целые минуты.

Об этом уже много раз говорилось о переполнении стека.Поиск, чтобы узнать больше.

LocalDate ld = LocalDate.of( 2019 , Month.APRIL , 30 ) ;
ZoneId z = ZoneId.of( "America/Edmonton" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;
Clock clock = Clock.fixed( instant , z ) ;

Теперь добавьте этот clock объект в ваши тесты.

ZonedDateTime zdt = ZonedDateTime.now( clock ) ;

Если вы хотите настоящие часы, используйте:

Clock clock = Clock.system( z ) ;
0 голосов
/ 30 апреля 2019

Вы можете использовать фиксированную дату

LocalDate date = LocalDate.parse("20190430000000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

Этот пример кода будет работать с java8 или выше.

EDIT1:

Предположение: Вы хотите написать тест, который использует фиксированную дату, но в производстве используется текущая дата. Вы можете использовать JUnit, какое-то внедрение зависимостей и Mockito.

Это абстрактный пример, который не будет компилироваться напрямую.

class XYZ {
    @Inject
    private DateProvider dateProvider;

    public void buildStr(StringBuilder str){
        LocalDate date = dateProvider.getDate();

        // do something with date
    }
}

class DateProvider {
    public Date getDate() {
        return new Date();
    }
}

class XYZTest {
    @Mock
    private DateProvider dateProvider;

    @InjectMocks
    private XYZ xyz;

    @Test
    public void test() {
        LocalDate fixedDate = LocalDate.parse("20190430000000", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        when(dateProvider.getDate()).thenReturn(fixedDate);

        StringBuilder builder = new StringBuilder();
        xyz.buildStr(builder);

        // verify builder contains what you expect
    }
}

В вашем классе обслуживания вы определяете дополнительный компонент, который предоставляет дату (здесь DateProvider). В тесте вы получаете тестируемый экземпляр вашего сервиса через аннотацию @InjectMocks, предоставленную Mocktio Он вставит любое поле, помеченное @Mock, в ваш тестируемый экземпляр в качестве макета. В своем тесте вы определяете, что макет должен делать, when().thenReturn(). Ваш производственный код будет использовать фактическую реализацию DateProvider, и вы получите текущую дату.

...