Goal of this Article
The goal of this article is to give you the fundamentals of testing a React component with Jest, with this knowledge you can hit the ground running when you start testing your own components. Ready? Let's start.
Sample Component
I have created a simple Card component in Codesandbox.
This component accepts a prop which handles when the Discover
button is clicked.
Here is the Codesandbox so you can follow along:
Codesandbox has still a ways to go when it comes to testing, I failed even getting a snapshot test to work so I recommend cloning down my repo here and following along on your local machine.
Installing JEST
The first thing we need to do before we can start using Jest is to install it. To install Jest run the following command:
npm install -D jest react-test-renderer
Thankfully, create-react-app
has this handled so we can just run npm test
to run our tests :)
Creating our tests directory
Jest looks for tests in directories named __tests__
, add the __tests__
directory to your Card
component.
Next thing we need to do is to create a test file in the __tests__
directory, we will call our file card.test.js
Your folder structure should now look like the following:
Creating a snapshot test
First run the command:
npm test
This will start Jest in watch mode, so any time we make changes our tests will rereun.
The first test we will write is a snapshot test.
Add the following code to your card.test.js
file:
import React from "react";
import Card from "..";
import Renderer from "react-test-renderer";
it("renders correctly", () => {
const tree = Renderer.create(<Card />).toJSON();
expect(tree).toMatchSnapshot();
});
This will create a JSON snapshot of our component in a directory called __snapshots__
, which means anytime the component changes this test will fail. Go ahead and change something in the component such as the text and you will get the following:
To remedy this, you simply need to update the snapshot by just pressing u
.
Testing the callback function
We are now going to use the library enzyme
to help us out, it gives us a lot of handy utils and saves us a lot of headaches.
We need to install a few dependencies:
npm install enzyme enzyme-adapter-react-16 --save-dev
Now add the following to the top of your test file:
import Adapter from 'enzyme-adapter-react-16';
import { mount, configure } from 'enzyme'
configure({adapter: new Adapter()});
For Enzyme to work we need to create an adapter, the adapter gets Enzyme working with your React version i.e. React 16.
Now let's add a new test:
it('triggers the callback function', ()=>{
})
Now let's fill out the body, I have commented each line so it is easy to understand.
// in order to test the callback function we first need to mock it
const onClickCallback = jest.fn()
// pass our mock function as the prop the Card
let card = mount(<Card handleClick={onClickCallback} />)
// find out button i.e. the button that triggers the callback and click it
const button = card.find('button').simulate('click')
// our mock function should have been called once
expect(onClickCallback).toHaveBeenCalledTimes(1)
Test that the correct value is passed from the callback function
Our callback function passes back the hardcoded string discover
, let's test to make sure that this is being passed correctly.
The function is similar to above except for the last line:
it('callback function is the passed the string discover', ()=>{
// in order to test the callback function we first need to mock it
const onClickCallback = jest.fn()
// pass our mock function as the prop the Card
let card = mount(<Card handleClick={onClickCallback} />)
// find out button i.e. the button that triggers the callback and click it
const button = card.find('button').simulate('click')
// test to see if our function was called with the right param
expect(onClickCallback).toHaveBeenCalledWith('discover')
})
Thanks for reading.
I hope you gained some knowledge, I will continue adding to this article so consider this draft 1 :)
Also I am a big fan of twitter and really close to 100 followers, so follow me there if you want, thanks.
Top comments (4)
The default tests directory of Jest is called
__tests__
with double underscore on each side? Really?! This pythonesque naming convention scares me. It looks alien in the JS world.Yeah I see your point, and you can change it but I personally I like it - it definitely stands out to other folders
Also updated the repo with all the tests included so you can see the final product!
Sorry guys, accidentally deleted all the CSS on this one when I was messing around with something, back in now!