@@ -26,32 +26,25 @@ npm install --save-dev jest babel-jest react-test-renderer identity-obj-proxy 'b
26
26
```
27
27
28
28
Because Gatsby handles its own Babel configuration, you will need to manually
29
- tell Jest to use ` babel-jest ` . The easiest way to do this is to add a ` "jest" `
30
- section in your ` package.json ` . You can set up some useful defaults at the same
31
- time:
32
-
33
- ``` json:title=package.json
34
- "jest" : {
35
- "transform" : {
36
- "^.+\\ .jsx?$" : " <rootDir>/jest-preprocess.js"
37
- },
38
- "testRegex" : " /.*(__tests__\\ /.*)|(.*(test|spec))\\ .jsx?$" ,
39
- "moduleNameMapper" : {
40
- ".+\\ .(css|styl|less|sass|scss)$" : " identity-obj-proxy" ,
41
- ".+\\ .(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$" : " <rootDir>/__mocks__/fileMock.js"
42
- },
43
- "testPathIgnorePatterns" : [" node_modules" , " .cache" ],
44
- "transformIgnorePatterns" : [
45
- " node_modules/(?!(gatsby)/)"
46
- ],
47
- "globals" : {
48
- "__PATH_PREFIX__" : " "
49
- },
50
- "testURL" : " http://localhost" ,
51
- "setupFiles" : [
52
- " <rootDir>/loadershim.js"
53
- ]
54
- }
29
+ 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:
30
+
31
+ ``` json:title=jest.config.js
32
+ module .exports = {
33
+ " transform" : {
34
+ " ^.+\\ .jsx?$" : " <rootDir>/jest-preprocess.js"
35
+ },
36
+ " moduleNameMapper" : {
37
+ " .+\\ .(css|styl|less|sass|scss)$" : " identity-obj-proxy" ,
38
+ " .+\\ .(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$" : " <rootDir>/__mocks__/fileMock.js"
39
+ },
40
+ " testPathIgnorePatterns" : [" node_modules" , " .cache" ],
41
+ " transformIgnorePatterns" : [" node_modules/(?!(gatsby)/)" ],
42
+ " globals" : {
43
+ " __PATH_PREFIX__" : " "
44
+ },
45
+ " testURL" : " http://localhost" ,
46
+ " setupFiles" : [" <rootDir>/loadershim.js" ]
47
+ }
55
48
```
56
49
57
50
The ` transform ` section tells Jest that all ` js ` or ` jsx ` files need to be
@@ -128,11 +121,47 @@ needed at first, but will make things a lot easier if you want to test
128
121
components that use ` Link ` or GraphQL.
129
122
130
123
``` js:title=__mocks__/gatsby.js
124
+ const React = require (" react" )
131
125
const gatsby = jest .requireActual (" gatsby" )
132
- module .exports = { ... gatsby, graphql: jest .fn (), Link: " Link" }
126
+
127
+ module .exports = {
128
+ ... gatsby,
129
+ graphql: jest .fn (),
130
+ Link: jest .fn ().mockImplementation (({ to, ... rest }) =>
131
+ React .createElement (" a" , {
132
+ ... rest,
133
+ href: to,
134
+ })
135
+ ),
136
+ StaticQuery: jest .fn (),
137
+ }
138
+ ```
139
+
140
+ This mocks the ` graphql() ` function, ` Link ` component, and ` StaticQuery ` component.
141
+
142
+ One more issue that you may encounter is that some components expect to be able
143
+ to use the ` location ` prop that is passed in by ` Router ` . You can fix this by
144
+ manually passing in the prop:
145
+
146
+ ``` js:title=src/__tests__/index.js
147
+ import React from " react"
148
+ import renderer from " react-test-renderer"
149
+ import BlogIndex from " ../pages/index"
150
+
151
+ describe (" BlogIndex" , () => {
152
+ it (" renders correctly" , () => {
153
+ const location = {
154
+ pathname: " /" ,
155
+ }
156
+
157
+ const tree = renderer .create (< BlogIndex location= {location} / > ).toJSON ()
158
+ expect (tree).toMatchSnapshot ()
159
+ }))
160
+ })
133
161
```
134
162
135
- This mocks the ` graphql() ` function and ` Link ` component.
163
+ For more information on testing page components, be sure to read the docs on
164
+ [ testing components with GraphQL] ( /docs/testing-components-with-graphql/ )
136
165
137
166
## Writing tests
138
167
@@ -150,11 +179,12 @@ import React from "react"
150
179
import renderer from " react-test-renderer"
151
180
import Bio from " ./Bio"
152
181
153
- describe (" Bio" , () =>
182
+ describe (" Bio" , () => {
154
183
it (" renders correctly" , () => {
155
184
const tree = renderer .create (< Bio / > ).toJSON ()
156
185
expect (tree).toMatchSnapshot ()
157
- }))
186
+ })
187
+ })
158
188
```
159
189
160
190
This is a very simple snapshot test, which uses ` react-test-renderer ` to render
@@ -220,95 +250,30 @@ config. First install `ts-jest`:
220
250
npm install --save-dev ts-jest
221
251
```
222
252
223
- Then edit the Jest config in your `package.json` to match this:
224
-
225
- ```json:title=package.json
226
- "jest": {
227
- "transform": {
228
- "^.+\\.tsx?$": "ts-jest",
229
- "^.+\\.jsx?$": "<rootDir>/jest-preprocess.js"
230
- },
231
- "testRegex": "(/__tests__/.*\\.([tj]sx?)|(\\.|/)(test|spec))\\.([tj]sx?)$",
232
- "moduleNameMapper": {
233
- ".+\\.(css|styl|less|sass|scss)$": "identity-obj-proxy",
234
- ".+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js"
235
- },
236
- "moduleFileExtensions": [
237
- "ts",
238
- "tsx",
239
- "js",
240
- "jsx",
241
- "json",
242
- "node"
243
- ],
244
- "testPathIgnorePatterns": ["node_modules", ".cache"],
245
- "transformIgnorePatterns": [
246
- "node_modules/(?!(gatsby)/)"
247
- ],
248
- "globals": {
249
- "__PATH_PREFIX__": ""
250
- },
251
- "testURL": "http://localhost",
252
- "setupFiles": [
253
- "<rootDir>/loadershim.js"
254
- ]
255
- }
256
- ```
257
-
258
- ## Testing components with Router
259
-
260
- When you test components they are not in a `Router`, meaning they don' t have
261
- access to some context and props that they may be expecting. The most common of
262
- these is the ` Link` component. In the example above we mock the ` Link` component
263
- as a string, which is the simplest solution and works for most uses. However
264
- sometimes you might want to test with the real ` Link` component. As of v2,
265
- Gatsby uses ` @reach/router` for navigation, which is good at handling test
266
- environments, and unlike React Router is happy to render ` Link` s outside of a
267
- ` Router` context. However there is a small issue related to the ` gatsby` mock.
268
- We can use a small workaround to avoid an error.
269
-
270
- First, remove the ` Link` mock from ` gatsby` :
271
-
272
- ` ` ` js:title=__mocks__/gatsby.js
273
- const gatsby = jest.requireActual(" gatsby" )
274
- module.exports = { ...gatsby, graphql: jest.fn () }
275
- ` ` `
276
-
277
- While the ` Link` component is exported by the main ` gatsby` package, it is
278
- actually defined in ` gatsby-link` . That in turn uses ` parsePath()` from
279
- ` gatsby` , which causes module resolution issues. Fortunately it' s an easy fix.
280
- You need to create a mock for `gatsby-link`, even though it will actually be the
281
- real module. You do this so that you can tell it to not try and use the mock
282
- `gatsby`:
283
-
284
- ```js:title=__mocks__/gatsby-link.js
285
- jest.unmock("gatsby")
286
- module.exports = jest.requireActual("gatsby-link")
287
- ```
288
-
289
- One more issue that you may encounter is that some components expect to be able
290
- to use the `location` prop that is passed in by `Router`. You can fix this by
291
- manually passing in the prop:
292
-
293
- ```js:title=src/__tests__/index.js
294
- import React from "react"
295
- import renderer from "react-test-renderer"
296
- import BlogIndex from "../pages/index"
297
-
298
- describe("BlogIndex", () =>
299
- it("renders correctly", () => {
300
- const location = {
301
- pathname: "/",
302
- }
303
-
304
- const tree = renderer.create(<BlogIndex location={location} />).toJSON()
305
- expect(tree).toMatchSnapshot()
306
- }))
253
+ Then update the configuration in `jest.config.js`, like so:
254
+
255
+ ```json:title=jest.config.js
256
+ module.exports = {
257
+ "transform": {
258
+ "^.+\\.tsx?$": "ts-jest",
259
+ "^.+\\.jsx?$": "<rootDir>/jest-preprocess.js"
260
+ },
261
+ "testRegex": "(/__tests__/.*\\.([tj]sx?)|(\\.|/)(test|spec))\\.([tj]sx?)$",
262
+ "moduleNameMapper": {
263
+ ".+\\.(css|styl|less|sass|scss)$": "identity-obj-proxy",
264
+ ".+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js"
265
+ },
266
+ "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
267
+ "testPathIgnorePatterns": ["node_modules", ".cache"],
268
+ "transformIgnorePatterns": ["node_modules/(?!(gatsby)/)"],
269
+ "globals": {
270
+ "__PATH_PREFIX__": ""
271
+ },
272
+ "testURL": "http://localhost",
273
+ "setupFiles": ["<rootDir>/loadershim.js"]
274
+ }
307
275
```
308
276
309
- For more information on testing page components, be sure to read the docs on
310
- [testing components with GraphQL](/docs/testing-components-with-graphql/)
311
-
312
277
## Other resources
313
278
314
279
If you need to make changes to your Babel config, you can edit the config in
@@ -318,3 +283,8 @@ though remember you may need to install the Babel 7 versions. See
318
283
319
284
For more information on Jest testing, visit
320
285
[the Jest site](https://jestjs.io/docs/en/getting-started).
286
+
287
+ For an example encapsulating all of these techniques--and a full unit test suite with [react-testing-library][react-testing-library], check out the [using-jest][using-jest] example.
288
+
289
+ [using-jest]: https://github.com/gatsbyjs/gatsby/tree/master/examples/using-jest
290
+ [react-testing-library]: https://github.com/kentcdodds/react-testing-library
0 commit comments