Unit testing is a great way to protect against errors in your code before you deploy it. While Gatsby does not include support for unit testing out of the box, it only takes a few steps to get up and running. However, there are a few features of the Gatsby build process that mean the standard Jest setup doesn’t quite work. This guide shows you how to set it up.
Note: For this guide, you will be starting with
gatsby-starter-default, but the
concepts should be the same or very similar for your site.
First, you need to install Jest and some more required packages. Install babel-jest and babel-preset-gatsby to ensure that the babel preset(s) that are used match what are used internally for your Gatsby site.
Because Gatsby handles its own Babel configuration, you will need to manually
tell Jest to use
babel-jest. The easiest way to do this is to add a
jest.config.js. You can set up some useful defaults at the same time:
Go over the content of this configuration file:
transformsection tells Jest that all
jsxfiles need to be transformed using a
jest-preprocess.jsfile in the project root. Go ahead and create this file now. This is where you set up your Babel config. You can start with the following minimal config:
- The next option is
moduleNameMapper. This section works a bit like webpack rules and tells Jest how to handle imports. You are mainly concerned here with mocking static file imports, which Jest can’t handle. A mock is a dummy module that is used instead of the real module inside tests. It is good when you have something that you can’t or don’t want to test. You can mock anything, and here you are mocking assets rather than code. For stylesheets you need to use the package
identity-obj-proxy. For all other assets, you need to use a manual mock called
file-mock.js. You need to create this yourself. The convention is to create a directory called
__mocks__in the root directory for this. Note the pair of double underscores in the name.
The next config setting is
testPathIgnorePatterns. You are telling Jest to ignore any tests in the
The next option is very important and is different from what you’ll find in other Jest guides. The reason that you need
transformIgnorePatternsis because Gatsby includes un-transpiled ES6 code. By default Jest doesn’t try to transform code inside
node_modules, so you will get an error like this:
This is because
gatsby-browser-entry.js isn’t being transpiled before running
in Jest. You can fix this by changing the default
__PATH_PREFIX__, which is usually set by Gatsby, and which some components need.
You need to set
testURLto a valid URL, because some DOM APIs such as
localStorageare unhappy with the default (
Note: if you’re using Jest 23.5.0 or later,
testURLwill default to
http://localhostso you can skip this setting.
- There’s one more global that you need to set, but as it’s a function you can’t
set it here in the JSON. The
setupFilesarray lets you list files that will be included before all tests are run, so it’s perfect for this.
Finally, it’s a good idea to mock the
gatsby module itself. This may not be
needed at first, but will make things a lot easier if you want to test
components that use
Link or GraphQL.
This mocks the
Link component, and
A full guide to unit testing is beyond the scope of this guide, but you can start with a simple snapshot test to check that everything is working.
First, create the test file. You can either put these in a
directory, or put them elsewhere (usually next to the component itself), with
.test.js. The decision comes down to your own
preference. In this guide, you will use the
__tests__ folder convention. To test the header component, create a
header.js file in
This is a very simple snapshot test, which uses
react-test-renderer to render
the component, and then generates a snapshot of it on the first run. It then
compares future snapshots against this, which means you can quickly check for
regressions. Visit the Jest docs to
learn more about other tests that you can write.
If you look inside
package.json you will probably find that there is already a
test, which just outputs an error message. Change this to use the
jest executable that you now have available, like so:
This means you can now run tests by typing
npm test. If you want you could
also run with a flag that triggers watch mode to watch files and run tests when they are changed:
npm test -- --watch.
Run the tests again now and it should all work! You may get a message about
the snapshot being written. This is created in a
__snapshots__ directory next
to your tests. If you take a look at it, you will see that it is a JSON
representation of the
<Header /> component. You should check your snapshot files
into a source control system (for example, a GitHub repo) so that any changes are tracked in history.
This is particularly important to remember if you are using a continuous
integration system such as Travis or CircleCI to run tests, as these will fail if the snapshot is not checked into source control.
If you make changes that mean you need to update the snapshot, you can do this
npm test -- -u.
If you are using TypeScript, you need to make two changes to your config.
Update the transform in
jest.config.js to run
jest-preprocess on files in your project’s root directory.
<rootDir> is replaced by Jest with the root directory of the project. Don’t change it.
jest.preprocess.js with the following Babel preset to look like this:
Once this is changed, you can write your tests in TypeScript using the
If you need to make changes to your Babel config, you can edit the config in
jest-preprocess.js. You may need to enable some of the plugins used by Gatsby,
though remember you may need to install the Babel 7 versions. See
the Gatsby Babel config guide for some examples.
For more information on Jest testing, visit the Jest site.