This guide will show you how to configure testing-library & Jest to work with Next.js.
For this guide we will use the basic 'create-next-app', which will automatically setup everything needed except testing.
I made a clone, in case future versions break the tests performed in this guide. We'll start by running the following commands:
$ git clone https://github.com/apardo04/nextjs-testing-library.git $ cd nextjs-testing-library $ npm run dev
Now, when you visit localhost:3000, you'll see "Welcome to Next.js!"
Like I mentioned 'create-next-app' doesn't come with built in testing. So first, let's install the necessary packages:
$ npm install --save-dev @testing-library/jest-dom @testing-library/react jest
Let's create a file in the root of the project called 'setupTests.js' and add the following to that file:
import '@testing-library/jest-dom/extend-expect'This will import necessary code from the jest-dom package when we run our tests.
The next file we need to create will also go in the root of our project and will be called 'jest.config.js', with the following code:
module.exports = { collectCoverageFrom: [ '**/*.{js,jsx,ts,tsx}', '!**/*.d.ts', '!**/node_modules/**', ], setupFilesAfterEnv: ['<rootDir>/setupTests.js'], testPathIgnorePatterns: ['/node_modules/', '/.next/'], transform: { '^.+\.(js|jsx|ts|tsx)$': '<rootDir>/node_modules/babel-jest' }, transformIgnorePatterns: [ '/node_modules/', '^.+\.module\.(css|sass|scss)$', ], moduleNameMapper: { '^.+\.module\.(css|sass|scss)$': 'identity-obj-proxy', }, }This is the configuration jest will use when we run our test script.
The final file that needs to be created in the root directory is '.babelrc', with the following:
{ "presets": ["next/babel"] }Next.js requires us to have '.babelrc' once we start testing or using some external libraries.
Our tests will reside in a folder that must be created and called '__tests__' in the root directory of the project.
In this folder you'll create a file called 'index.tests.js' and include the following code:
import React from 'react' import { render } from '@testing-library/react' import Home from '../pages/index.js' test('renders deploy link', () => { const { getByText } = render(<Home />) const linkElement = getByText( /Instantly deploy your Next.js site to a public URL with ZEIT Now./ ) expect(linkElement).toBeInTheDocument() })This is a basic test that will check if the text "Instantly deploy your Next.js site to a public URL with ZEIT Now" is present in the DOM.
Our project file structure should now look like this:
Now, we're going to edit the scripts block in the 'package.json', like so:
"scripts": { "test": "jest", "dev": "next dev", "build": "next build", "start": "next start" },We've added a script called "test" that will run "jest".
Now for the fun part. Run the following in your command line:
npm run test
You should see successful output like so:
Didn't get the same result? Stuck? Or want to discuss? Leave a message in the Disqus Thread or message me on Twitter.