#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
)
);
Но нам лучше не генерировать значения в модульных тестах — это может быть трудно воспроизвести, если модульные тесты не прошли один раз.