Aaron Presley

← Writing
Mocking the Javascript Intl Object with Jest

December 4, 2017

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().