Skip to content

Jest Snapshot Testing With Dates and Times

Erica Pisani
Erica Pisani
3 min read

Snapshot testing is great for quickly creating unit tests for components by getting a ‘snapshot’ of what a component looks like when it’s rendered on the page given certain prop values. This removes the need to manually check the amount of specific elements being rendered on the component, or what individual pieces of text are based on the values of props.

Let’s say that the component that you want to test using Jest snapshots has props that contain dates and times that are based on the current date/time. This can make snapshot testing a bit annoying as you’d have to update your snapshot test(s) every minute, and no one wants to do that! Another problem that you may run into is that if you use a service like CircleCI to run your tests, the date/time will be based on the timezone of the CircleCI server.

By leveraging the wonderful moment-timezone library, we can easily get around these issues in order to benefit from the easy creation of unit tests and ease of maintainability that Jest snapshots gives us.

Let’s take a look at a component that uses dates and times:

import React, { Component } from 'react';
import moment from 'moment';
import './App.css';
import PropTypes from 'prop-types';

class App extends Component {
  static propTypes = {
    currentDay: PropTypes.string.isRequired,
  };

  static defaultProps = {
    currentDay: moment().format("MMM Do YYYY h:mm:ss a")
  };

  render() {
    const { currentDay } = this.props;

    return (
      <div className="App">
        Hello world!
        <p>The day and time is currently {currentDay}</p>
      </div>
    );
  }
}

export default App;

Which renders the following on your browser:

Initial application render

After writing a small snapshot test and creating the initial snapshot, this is what you’ll see once you wait a few minutes, and run your snapshot tests again in your local environment:

Initial snapshot test result

And this is what happens on a continuous deployment/integration service (in this example we’re using Gitlab’s integrated CI services):

Initial snapshot test result on CI

Based on the time in the above image, we know that the servers are using UTC, whereas we are using EST.

So how do we go about creating the conditions in our unit test so that we can run our snapshots locally and on a CI service?

First, let’s update our unit test to pass a hard coded date to our component that’s created using the moment library.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import renderer from 'react-test-renderer';
import moment from 'moment';


it('renders without crashing', () => {
  let props = {
    currentDay: moment("2017-09-15 09:30:00").format("MMM Do YYYY h:mm:ss a")
  };

  const tree = renderer.create(<App {...props} />).toJSON();
  expect(tree).toMatchSnapshot();
});

Let’s run our tests now that we’ve made that change….

modified App Render test results

Perfect! Now our snapshot test won’t be failing due to the clock continuing to tick.

But what about the CI service? Our change doesn’t fix the problem that we saw earlier with the difference in timezones.

Rather than using the standard ‘moment’ library like we did earlier, we can use the ‘moment-timezone’ library to enforce a particular timezone in our tests. Our test file should now look like the following:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import renderer from 'react-test-renderer';
import moment from 'moment-timezone';


it('renders without crashing', () => {
  moment.tz.setDefault('EST');
  let props = {
    currentDay: moment("2017-09-15 09:30:00").format("MMM Do YYYY h:mm:ss a")
  };

  const tree = renderer.create(<App {...props} />).toJSON();
  expect(tree).toMatchSnapshot();
});

After committing our changes and pushing them to our repository on Gitlab…

modified CI test results

We now have a snapshot unit test that allows us to assert that our component renders the date and the time without needing to constantly update it or worry about the test’s behaviour when it’s running on servers that use a different timezone than we are.


📫
Enjoy this post? Subscribe to be notified when I publish new content!
testing

Comments


Related Posts

Members Public

How to change the version of an npm package associated with a specific tag

If publishing experimental npm packages is a somewhat regular part of your development workflow, you've likely experienced some nerves around publishing that package incorrectly such that it becomes the version that anyone newly installing or upgrading the package gets. If you find that you accidentally did exactly this

How to change the version of an npm package associated with a specific tag
Members Public

Testing a project contained in a monorepo

A ‘monorepo’ is the term used to describe the organization of multiple distinct projects with well-defined relationships into a single code repository1 rather than having each project be in its own dedicated repository. Monorepos have been around for a while, but if you haven’t worked with them before, figuring

Members Public

Testing Typescript Types

The ability to inform and educate us on how a package functions and behaves through the use of types is one of Typescript’s biggest strengths as a language, alongside its’ ability to gradually be adopted within an existing Javascript project. Unfortunately, we can’t always expect that those types