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