Testing dates with Jest
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:
- Getting always the same date, in order to state the assertions.
- Making the formatting independent of the timezone of the machine running the tests. Yes, the result of
moment(date).format()
is not the same in GMT than in some other timezone, and we don't want our tests to break some CI pipeline.
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.