Сбой тестов на ci при использовании joda time - PullRequest
0 голосов
/ 06 апреля 2019

Мои тесты начали проваливаться, когда я запускаю их на CI-сервере, они нормально запускаются на моей машине.Я получаю ошибку подтверждения в этой строке

assertEquals(DateTime(1554091200000), generateNextTime())

Я получаю ошибку

java.lang.AssertionError: 
Expected :2019-04-01T00:00:00.000-04:00
Actual   :2019-03-31T20:00:00.000-04:00

Ответы [ 2 ]

1 голос
/ 07 апреля 2019

ТЛ; др

java.time.Instant.ofEpochMilli( 1_554_091_200_000L ) 

Всегда указывайте часовой пояс

Вы узнали, что классы даты и времени прибегают к неявному применению текущего часового пояса JVM по умолчанию, если вы не указали его. Это означает, что ваши результаты могут отличаться во время выполнения. Хуже того, ваши результаты могут отличаться во время выполнения , поскольку любой код в любом потоке любого приложения в JVM может изменить значение по умолчанию !

Лучше всегда указывать желаемый / ожидаемый часовой пояс. И если это важно для вашего приложения, подтвердите зону с пользователем.

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

ZoneId

Укажите собственное имя часового пояса в формате Continent/Region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 2-4 буквенные сокращения, такие как EST или IST, поскольку они не истинных часовых поясов, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  

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

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Joda-Time

Вы должны знать, что отличный проект Joda-Time сейчас находится в режиме обслуживания. Его создатель, Стивен Колебурн, использовал полученные там уроки, чтобы найти JSR 310 и его реализацию, классы java.time .

См. Маркеры ниже для более старых Android и Java.

Класс java.time.Instant представляет момент в UTC. Внутренне это число наносекунд с первого момента 1970 года в UTC.

Instant instant = Instant.ofEpochMilli( 1_554_091_200_000L ) ;

ZoneId z = ZoneId.of( "America/Puerto_Rico" ) ;
ZonedDateTime zdt = instant.atZone( z ) 

Instant и ZonedDateTime представляют один и тот же момент, одну и ту же точку на временной шкале. Тот же самый момент одновременно отображается по-разному, что видно по настенным часам, используемым людьми определенного региона (часового пояса).

См. Этот код, запущенный в режиме реального времени на IdeOne.com .

instant.toString (): 2019-04-01T04: 00: 00Z

zdt.toString (): 2019-04-01T00: 00-04: 00 [America / Puerto_Rico]

Clock

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

Переполнение стека поиска

Переполнение стека поиска. Все эти темы уже были рассмотрены много раз.

Совет: используйте поисковую систему в Интернете, такую ​​как DuckDuckGo, с критерием site:stackoverflow.com. Средство поиска в переполнении стека является анемичным, неисправным и смещенным в сторону просмотра вопросов, а не ответов.


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Проект Joda-Time , теперь в режиме обслуживания , рекомендует выполнить переход на классы java.time .

Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

  • Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11 и более поздние версии - часть стандартного Java API с комплексной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и JavaSE 7
    • Большинство функций java.time перенесены в Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии реализации связки Android java.time классы.
    • Для более ранних версий Android (<26) проект <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP адаптируется ThreeTen-Backport (упомянуто выше).См. Как использовать ThreeTenABP… .
0 голосов
/ 06 апреля 2019

В основном, что происходило, было то, что время joda использовало другой часовой пояс, чем то, что ожидали мои тесты.

Я решил это, добавив это в свои тесты.

@Before
fun setUp() {
    DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getTimeZone("CET")))
}

Так что теперьЯ использую один и тот же часовой пояс везде, где я запускаю свои тесты

...