Testing dates with Jest

October 31, 2019

This post shows how to add tests to JavaScript code that uses Date or moment functions. I will explain how to mock dates and how to make tests independent from the timezone.

I was working on some refactoring task, where we would replace some moment calls with utility functions, like the following function:

// date-utils.ts
export const formatDateTime = (date: Moment = moment()) =>
  moment(date).format(HTML5_FMT.DATETIME_LOCAL);

Besides the refactoring, I thought it would be nice to add some unit tests to the date utils file. But then I realized there were two problems to solve there:

This is the test spec file, where I am using a Jest mock to always return the same date.

// date-utils.spec.ts
import { formatDateTime } from "./date-utils";

import moment = require("moment");

describe("dates utils", () => {
  beforeEach(() => {
    Date.now = jest.fn(() => 1572393600000); // 2019-10-30T00:00Z0 (GMT)
  });

  it("should format empty date as datetime", () => {
    const result = formatDateTime();
    expect(result).toBe("2019-10-30T00:00");
  });

  it("should format a non empty date as datetime", () => {
    const result = formatDateTime(moment("2019-10-31T12:34:56"));
    expect(result).toBe("2019-10-31T12:34");
  });
});

That solved the first problem, but what about the second one?

Well, I had to deeply dig to find the answer. I read about using some libraries like MockDate, but it actually didn't work with timezones so my first test above would break returning "2019-10-30T01:00" since my computer is in GMT+1.

The solution was passing and ENV variable to jest in the test script of package.json, like so:

// package.json
{
  "scripts": {
    "test": "TZ=UTC jest"
  }
}

Now, our machine is virtually located in GMT, so we can predict the result of any date formatting or parsing, and our tests won't break.

Credits

Photo by Fabian Albert on Unsplash.

About the author: Juangui Jordán

Full-stack engineer at mimacom, I'm moving towards frontend and UX. Always keen to learn and teach whatever I have to offer to others.

Comments
Join us