тест календаря проходит только при использовании AndroidJunit4

#android #unit-testing #kotlin #junit4

#Android #модульное тестирование #kotlin #junit4

Вопрос:

У меня странный случай. Я запускаю локальный тест и использую класс Calendar в рамках этого теста.

при аннотировании тестового класса с помощью @RunWith(AndroidJUnit4::class) тест проходит, в противном случае тест завершается неудачей.

тестовый код не включает никакой библиотеки среды Android

вот мой класс

 class MyDateUtils(private val calendar: Calendar) {

    fun getDates(): Long{
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
        return calendar.timeInMillis
    }
}
  

и вот тестовый пример, этот проходит

 @RunWith(AndroidJUnit4::class)
class MyDateUtilsTest {

    private lateinit var calendar: Calendar
    private lateinit var dateUtils: MyDateUtils

    @Before
    fun init() {
        calendar = Calendar.getInstance()
        calendar.timeInMillis = 1592422768000
        dateUtils = MyDateUtils(calendar)
    }

    @Test
    fun `when get dates is called with wednesday day should return sunday of the same week`() {
        val expected = 1592163568000

        val actual = dateUtils.getDates()

        assertEquals(expected, actual)

    }
}
  

теперь, когда я удаляю @RunWith(AndroidJUnit4::class) , тест завершается неудачей с этим сообщением об ошибке java.lang.AssertionError: Expected :1592163568000 Actual :1592768368000

P.S ожидаемое поведение заключается в том, что getDates() метод возвращает воскресенье в течение той же недели. но без @RunWith(AndroidJUnit4::class) этого верните в следующее воскресенье (на следующей неделе).

Комментарии:

1. Я бы предположил, что это где-то проблема с локализацией из-за запуска теста на компьютере, а не на устройстве. После установки текущего времени, если вы сделаете вызов getTimeInMillis (перед установкой дня), это сделает его согласованным?

2. Привет, спасибо за комментарий. Я не уверен, что именно вы хотите, чтобы я попробовал. можете ли вы уточнить?

3. Это может быть как-то связано с языковым стандартом по умолчанию, который может быть изменен при запуске с AndroidJUnit4. Интересно, отличается ли первый день недели в зависимости от того, используете ли вы это. 1. Вы могли бы написать несколько отладочных инструкций, чтобы ответить на этот вопрос. 2. Можете ли вы опубликовать код, который вычисляет дату? (что вычисляет значение, возвращаемое getDates() ).

4. Привет, @PedroLoureiro . Я думаю, вы правы. это связано с локализацией. Я пробовал отладку в обоих случаях и проверку на val first = calendar.firstDayOfWeek и я обнаружил, что результаты разные, поэтому в моем тесте я установил языковой стандарт следующим образом locale = Locale("US") calendar = Calendar.getInstance(locale) и прошел. рассмотрите возможность написания этого в качестве ответа, и я отмечу его как правильный. Спасибо

5. Я говорю, calendar.timeInMillis = 1592422768000; calendar.getTimeInMillis(); dateUtils = MyDateUtils(calendar) заставляет ли это работать? Calendar s создаются с текущим временем (которое зависит от локали), и когда вы устанавливаете timeInMillis , оно фактически не пересчитывается, пока вы не вызовете get метод. Таким образом, возможно, что при установке времени, а затем дня ожидающее изменение времени перезаписывается / игнорируется. Вызов get метода после установки времени приведет к его блокировке. Calendars являются странными и сложными

Ответ №1:

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

В разных локализациях первый день недели отличается, и это может привести к сбою или прохождению тестов в зависимости от исполнителя.