В JavaScript Land, издевательство над глобальными объектами браузера может быть чем -то большей болью для тестов. Поиск Stackoverflow дает множество сложных ответов. Некоторые предлагают использовать сторонние библиотеки. Некоторые, которые перезаписывают сам глобальный объект …. Но Jest уже обладает встроенной возможностью, и это не так уж и плохо:
Итак, допустим, у вас есть метод, который получает часовой пояс пользователя или смещение часового пояса. (Смещение часового пояса используется иногда, так как IE11 не поддерживает легко чтение часового пояса , но я отступаю)
/**
* Useful when passing the browser timezone to a backend Java API that reads a timezone in using ZoneId.of(tz),
* as both 'America/Chicago' and '-0600' are valid values when passed to the Java API.
* The Offset is used to handle IE11 and other older browsers.
*/
export const getUserTimeZoneOrOffset = () => {
let timeZone;
try {
timeZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;
} catch (error) {
// Ignore if this happens, and just use the fallback
}
if (!timeZone) {
//Could not get a browser timezone, maybe IE11, so instead use timezoneOffset formatted for Java
// https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZoneOffset.html#of(java.lang.String)
const offset = new Date().getTimezoneOffset();
//Yeah this offset +/- seems backwards,
// but JS actually returns a positive when local tz is behind UTC (like for US tzs)
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
// e.g. offset = 300, timeZone='-0500'
const plusMinus = offset <= 0 ? '+' : '-';
//leftpad a 0 when needed for two digits
const hours = ('0' + Math.floor(Math.abs(offset) / 60)).slice(-2);
const minutes = ('0' + (offset % 60)).slice(-2);
timeZone = `${plusMinus}${hours}${minutes}`;
}
return timeZone;
};
Теперь, чтобы проверить это, нам нужно издеваться как глобусы intl и date javaScript. Мы можем сделать это с помощью Jest’s Spyon Метод временно заменить глобальный метод нашей собственной реализацией. Обратите внимание, что мы настроем шпион в Передеда и сбросить все в После обучения Анкет Настройка работает примерно так:
import { getUserTimeZoneOrOffset } from './timeZoneUtils.js';
describe('getUserTimeZoneOrOffset', () => {
let mockOffset;
let mockTimezone;
beforeEach(() => {
mockTimezone = undefined;
jest.spyOn(Intl, 'DateTimeFormat').mockImplementation(() => ({
resolvedOptions: () => ({
timeZone: mockTimezone
})
}));
mockOffset = undefined;
jest
.spyOn(Date.prototype, 'getTimezoneOffset')
.mockImplementation(() => mockOffset);
});
afterEach(() => {
jest.restoreAllMocks();
});
test('returns timezone name when found', () => {
mockTimezone = 'America/Chicago';
const result = getUserTimeZoneOrOffset();
expect(result).toBe('America/Chicago');
});
test.each([
[300, '-0500'],
[150, '-0230'],
[-60, '+0100'],
[-330, '+0530'],
[0, '+0000'],
[-765, '+1245']
])('timezoneOffset for %i is %s', (offset, expected) => {
mockOffset = offset;
const result = getUserTimeZoneOrOffset();
expect(result).toBe(expected);
});
});
Но это все! Не нужно импортировать дополнительную библиотеку. Это все поставляется непосредственно в самом шутке!
Оригинал: “https://dev.to/jeffsheets/mock-intl-and-date-globals-in-jest-easily-1co5”