Recipes for unit tests when working with date and time in React/JavaScript

Tools

Mindset

  • handle only one format in your application. It doesn't really matter if you decide to work with JavaScript Date Objects (the value of new Date()) or its static method Date.now() which returns the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC. Just stick to one and re-format when needed (with date-fns since moment stopped service)
  • always stub or mock real date and time functions. Never rely on any system time, this will get you into trouble, I promise.

Examples

import mockdate from "mockdate"const mockdateInit = 1580782960 // 2020-02-04T02:22:40describe("yourTest", () => {
beforeEach(() => {
mockdate.set(mockdateInit)
})
afterAll(() => {
mockdate.reset()
})
})

...
const anyOtherDate = 1580782970
...
...
it("should be in the future", () => {
const result = anyOtherDate > mockdateInit
expect(result).toBeTruthy()
})
...

...
const mockDateInit = 1580782960 // 2020-02-04T02:22:40
const mockDateNextFullMinute = 1580782980 // 2020-02-04T02:23:00
const mockDateMinuteAfterNext = 1580783040 // 2020-02-04T02:24:00
const mockDateAfterAfter3Minutes = 1580783100 // 2020-02-04T02:25:00
...
...
jest.useFakeTimers() // make sure Jest uses them
...
it("should update every full minute after first update", () => {
const { result } = renderHook(() => useCurrentTime())
Mockdate.set(mockdateMinuteAfterNext)
act(() => jest.advanceTimersByTime(100000))
expect(result.current).toEqual(Math.floor(mockdateMinuteAfterNext / 1000)) Mockdate.set(mockdateAfterAfter3Minutes)
act(() => jest.advanceTimersByTime(60000))
expect(result.current).toEqual(Math.floor(mockdateAfterAfter3Minutes / 1000))
})

Wrap it up

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store