Mocking the Javascript Intl Object with Jest

I wrote a method to check whether or not the given environment (the browser or the node environment) has native Intl support. There's a bit of a trick to this because there's three possible states:

  1. Intl is not supported
  2. Intl is supported, but was only installed with system-icu (the default for node)
  3. Intl is supported, and was installed with full-icu support

Here's the method, pulled almost directly from node documentation:

export const supportsIntl = (doFullCheck = false) => {
  if (!doFullCheck) {
    return typeof Intl === 'object';
  }

  try {
    const january = new Date(9e8);
    const spanish = new Intl.DateTimeFormat('es', { month: 'long' });
    return spanish.format(january) === 'enero';
  }
  catch (err) {
    return false;
  }
};

For my case I don't always want to require a full ICU to be installed, but I at least want to ensure Intl is present.

And here's my test:

describe('supportsIntl()', () => {
  describe('when Intl not present', () => {
    beforeEach(() => {
      Intl = undefined;
    });

    it('should be false for basic check', () => {
      expect(supportsIntl()).toEqual(false);
    });

    it('should be false for full check', () => {
      expect(supportsIntl(true)).toEqual(false);
    });
  });

  describe('when limited Intl present', () => {
    beforeEach(() => {
      Intl = {
        DateTimeFormat: () => {
          throw new Error(`Error from DateTimeFormat`);
        },
      };
    });

    it('should be true for basic check', () => {
      expect(supportsIntl()).toEqual(true);
    });

    it('should be false for full check', () => {
      expect(supportsIntl(true)).toEqual(false);
    });
  });

  describe('when full Intl present', () => {
    beforeEach(() => {
      Intl = {
        DateTimeFormat: () => {
          return {
            format: () => 'enero',
          }
        },
      };
    });

    it('should be true for basic check', () => {
      expect(supportsIntl()).toEqual(true);
    });

    it('should be true for full check', () => {
      expect(supportsIntl(true)).toEqual(true);
    });
  });
});

Your linter might not like overwriting the Intl object, so you'll have to throw in a little /* eslint-disable no-global-assign */ in there.

This should help those of you who were trying unsuccessfully to use jest.mock().