Поблочное тестирование класс с Часами Java 8

Java 8 представлен java.time.Clock который может использоваться в качестве аргумента многим другой java.time объекты, позволяя Вам ввести реальные или поддельные часы в них. Например, я знаю, что можно создать a Clock.fixed() и затем звоните Instant.now(clock) и это возвратит фиксированное Instant Вы обеспечили. Это звучит идеально подходящим для поблочного тестирования!

Однако я испытываю затруднения при выяснении, как лучше всего использовать это. У меня есть класс, подобный следующему:

public class MyClass {
    private Clock clock = Clock.systemUTC();

    public void method1() {
        Instant now = Instant.now(clock);
        // Do something with 'now'
    }
}

Теперь, я хочу к модульному тесту этот код. Я должен смочь установить clock произвести зафиксированные времена так, чтобы я мог протестировать method() в разное время. Очевидно, я мог использовать отражение для установки clock участник к определенным значениям, но было бы хорошо, если бы я не должен был обращаться к отражению. Я мог создать общественность setClock() метод, но это чувствует себя неправильным. Я не хочу добавлять a Clock аргумент методу, потому что реальный код не должен касаться передачи в часах.

Каков лучший подход для обработки этого? Это - новый код, таким образом, я мог реорганизовать класс.

Править: Для разъяснения я должен смочь создать сингл MyClass объект, но смочь иметь тот один объект видит два различных значения часов (как будто это были обычные системные часы, отсчитывающие вперед). По сути, я не могу передать фиксированные часы в конструктора.

58
задан 21 November 2014 в 20:43

1 ответ

Для запуска определенно введите Clock в класс под тестом, как рекомендуется @Jon Стрельбой по тарелочкам. Если Ваш класс только требует одного времени, то просто передают в Clock.fixed(...) значение. Однако, если Ваш класс ведет себя по-другому через время, например, он делает что-то во время A, и затем делает что-то еще во время B, затем отмечает, что часы, созданные Java, неизменны и таким образом не могут быть изменены тестом для возврата времени когда-то и затем времени B в другом.

Насмешка, согласно принятому ответу, является одной опцией, но действительно сильно связывает тест к реализации. Например, как один комментатор указывает, что если класс при проверочных вызовах LocalDateTime.now(clock) или clock.millis() вместо clock.instant()?

альтернативный подход, который является немного более явным, легче понять, и может быть более устойчивым, чем насмешка, должен создать реальную реализацию Clock, который является изменяем , так, чтобы тест мог ввести его и изменить его по мере необходимости. Это не трудно реализовать. См. https://github.com/robfletcher/test-clock для хорошего примера этого.

MutableClock c = new MutableClock(Instant.EPOCH, ZoneId.systemDefault());
ClassUnderTest classUnderTest = new ClassUnderTest(c);

classUnderTest.doSomething()
assertTrue(...)

c.instant(Instant.EPOCH.plusSeconds(60))

classUnderTest.doSomething()
assertTrue(...)
2
ответ дан 1 November 2019 в 14:05

Другие вопросы по тегам:

Похожие вопросы: