Before we actually begin to write component test we will add some extra configuration for Jest to make this easier for us. As mentioned earlier, Jest is a zero-configuration library so these steps are not strictly necessary. Jest can automatically create and match snapshots of our components but with these improvements the snapshots that are generated will be much easier for us as a developer to read and compare.
We are also going to include an open source library called enzyme
that will
help us to mount our components in isolation and provide us with the ability to
interact with them, clicking on controls and testing the expected results,
instead of simply generating a snapshot of the returned JSX.
A configuration will also be added to tell Jest that we are using CSS modules so that it can parse our components without encountering an error.
Finally we will create a spec helper file that is available to all tests so that some configuration and mock data can be shared.
The enzyme package allows us to work with components inside of tests by either creating a "shallow" version of it (only the tested component will be rendered) or "mount" the full DOM (the component and all of it's children are rendered. Additionally you can interact with the component by simulating events such as a "click").
We will first install this as a development dependency. Since we are using React
version 16 we also need to install the enzyme-adapter-react-16
package.
yarn add --dev enzyme enzyme-adapter-react-16
Normally enyzme would not need any configuration but as mentioned we need the
enzyme-adapter-react-16
adapter for enzyme due to our React.js package
version. This means that in every test file where we use enzyme we would have to
import the adapter and instruct enzyme to use it. Instead of copying this to
every file we can inform Jest that we have a "spec helper" file. This file will
automatically be loaded into every test file in the project making it the ideal
place to place shared configuration.
Let's create a spec-helper.js
file in the app/js/
directory. Here we will
import the React 16 enzyme adapter, the configure
method from enzyme and apply
the configuration.
Additionally we need to import a polyfill 2 for the requestAnimationFrame
method. This package already comes ad a dependency from enzyme so we do not need
to install anything additionally. This polyfill is required to handle warnings
given by React 16 when mounting our components.
// app/js/spec-helper.js
import 'raf/polyfill';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
The final step is to inform Jest about our spec helper location. We do this by
creating a jest
section in our package.json
and passing the location of the
file to the setupTestFrameworkScriptFile
key.
// package.json
...
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack -p",
"lint:all": "eslint app/js/*",
"lint:fix": "eslint app/js/* --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
},
+ "jest": {
+ "setupTestFrameworkScriptFile": "./app/js/spec-helper.js"
+ },
...
By default when you "snapshot" a component you creates a representation of the JSX returned by the component and writes it to a snapshot file. The default snapshots from Jest can be quite verbose and hard to read. They can also cause problems across different systems just as Mac OS X and Linux as they are generated slightly differently.
We can create simpler snapshots that are constant across systems by adding the
package enzyme-to-json
. This plugin takes the components that we will be
mounting with enzyme
and overrides the default snapshot that Jest would have
made.
We will install it as a development dependency with Yarn.
yarn add --dev enzyme-to-json
We then simply have to update the "jest"
section of our package.json
again
with a new configuration key snapshotSerializers
which accepts an array of
serializers to be used.
// package.json
"jest": {
- "setupTestFrameworkScriptFile": "./app/js/spec-helper.js"
+ "setupTestFrameworkScriptFile": "./app/js/spec-helper.js",
+ "snapshotSerializers": ["enzyme-to-json/serializer"]
},
So that Jest can understand that we are using CSS modules we must install the
jest-css-modules
package.
yarn add --dev jest-css-modules
Again we update the "jest"
section of the package.json
to tell Jest to run
all test files through the jest-css-modules
parser, which will prevent any
errors from occurring while running tests.
"jest": {
"setupTestFrameworkScriptFile": "./app/js/spec-helper.js",
- "snapshotSerializers": ["enzyme-to-json/serializer"]
+ "snapshotSerializers": ["enzyme-to-json/serializer"],
+ "transform": {
+ ".*": "./node_modules/jest-css-modules"
+ }
},
Finally we will will add some mock data for the points
array to the spec
helper so that it can be shared across all specs, instead of defining mock data
in every file. This prevents us from having to go through all tests are update
the mock data structure if our data changes.
Add the following mock data to spec-helper.js
.
// app/js/spec-helper.js
import 'raf/polyfill';
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
+ export const pointsMock = [
+ {
+ id: 'point-1',
+ x: 450,
+ y: 110,
+ details: {
+ name: 'The Wall',
+ house: "Night's Watch",
+ words: 'Night gathers, and now my watch begins.'
+ },
+ favourite: true
+ },
+ {
+ id: 'point-2',
+ x: 375,
+ y: 355,
+ details: {
+ name: 'Winterfell',
+ house: 'Stark',
+ words: 'Winter is Coming'
+ },
+ favourite: false
+ }
+ ];
Now we everything we need to complete our testing is ready. We'll continue in
the next step by testing the Map
component.