Рубрики
Без рубрики

Измешивайте Intl и даты Globals в шутку (легко!)

В JavaScript Land, издевательство над глобальными объектами браузера может быть чем -то большей болью для тестов. Поиск ST … Tagged с JavaScript, тестирование, шутка.

В 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”