Время тестирования NodeJS с разным временем суток и часовым поясом

#node.js #unit-testing #datetime #jestjs

#node.js #модульное тестирование #дата и время #jestjs

Вопрос:

У меня ситуация, когда сегодняшняя дата помещается в базу данных, и я использую ванильный код.

 const todayCloseDate = new Date().toISOString().slice(0, 10);
  

Это, очевидно, создает проблему с моим часовым поясом (CST), который после 5:00 вечера дата становится значением следующего дня. Я изменил обработку пакета data-fns (moments.js это не вариант).

 const todayCloseDate = DF.format(new Date(), 'yyyy-MM-dd');
  

Все работает так, как ожидалось. Мой вопрос в том, как модульно протестировать такое изменение? Для этого потребуется внести изменения в системное время локальной машины, чтобы локально запускать тесты, а также в любой среде тестирования, которая будет запускать тесты в конвейере CI / CD (это были бы CircleCI и Jenkins).

Можно ли запустить тестовый сценарий, который бы охватывал такую ошибку и обеспечивал исправление? Мой тестовый бегун — шутка.

Ответ №1:

При написании модульных тестов для даты (или случайного класса) вам необходимо убедиться, что ваша дата внутри теста всегда одинакова. Один из способов сделать это — переопределить его реализацию:

 jest.spyOn(global.Date, 'toISOString').mockReturnValue('2011-10-05T14:48:00.000Z')// whatever date suits you;
  

А затем напишите свой тест для этой даты.

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

1. Это происходит где-то, но не до такой степени, на которую я смотрю… Мне нужно проверить, что в одном сценарии, когда toISOString() будет возвращен следующий день DF..... , будет возвращен правильный день в тот же час

Ответ №2:

На самом деле, установка статического часового пояса как @Heri Hehe Setiawan была бы для вас решением. Если часовой пояс заморожен, вы можете предоставить своим тестам некоторые граничные значения для дат.

Другим подходом может быть макет Date конструктора и функций Date.parse() , Date.now() либо напрямую предоставляя макет, либо с помощью некоторых сторонних компонентов, таких как timezone-mock.

И, наконец, вы можете обратиться к new Date().getTimezoneOffset() для генерации значений граничного регистра:

 const minuteAfterMidnightAtUTC = 
  new Date(
    new Date().setHours(
      0, -new Date().getTimezoneOffset()   1, 0, 0
    )
  );
  

Но нам лучше не генерировать значения в модульных тестах — это может быть трудно воспроизвести, если модульные тесты не прошли один раз.