Chaerin.dev

React Unit Testing with Jest

What is Unit Testing?

Before diving into unit testing, let’s first understand why we write test code. It’s to ensure that the code we write functions correctly as intended.

There are three main types of tests in frontend development:

  • Unit Testing: This is the smallest unit of testing, typically at the method level. It tests things like when function A is called, result B is expected.

  • Integration Testing: This tests the compatibility issues between modules during the integration process. Unlike unit tests, integration tests are not independent from other components.

  • E2E Testing: This tests the entire system including its build and deployment process.

In simpler terms, unit testing focuses on testing individual components to ensure that the methods inside them produce the intended results.

Jest Syntax

Setting up Jest

To perform unit testing with Jest, you need to first install necessary packages in your project. Run yarn add jest enzyme enzyme-adapter-react-16.

Once installed, add the following script to your package.json:

"scripts": {
    ...
    "test": "jest",
    ...
  },

Create a tests folder and add a file named sample.spec.js or sample.test.js:

// tests/sample.spec.js
test('This is a sample', () => {
  expect(true).toBe(true)
})

Running yarn test will produce the following output:

To use JSX syntax, add the following code to babel.config.js:

module.exports = {
  presets: ['@babel/preset-env', '@babel/preset-react'],
};

Writing Test Code

Here’s an example of test code using a simple Counter component:

import React, { useState } from 'react'

const Counter = () => {
  const [count, setCount] = useState(0)
  return (
    <div>
      <button className="prev" onClick={() => setCount(count - 1)}>
        &lt;
      </button>
      <p className="page">{count}</p>
      <button className="next" onClick={() => setCount(count + 1)}>
        &gt;
      </button>
    </div>
  )
}

export default Counter
import { configure, shallow } from 'enzyme'
import React from 'react'
import Adapter from 'enzyme-adapter-react-16'
import Counter from '../src/components/Counter'

configure({ adapter: new Adapter() })

describe('<Counter/>', () => {
  it('is rendered', () => {
    const wrapper = shallow(<Counter />)
    expect(wrapper).toBeTruthy()
  })
  it('click left arrow', () => {
    const wrapper = shallow(<Counter />)
    wrapper.find('.prev').simulate('click')
    expect(wrapper.find('.page').text()).toBe('-1')
  })
  it('click right arrow', () => {
    const wrapper = shallow(<Counter />)
    wrapper.find('.next').simulate('click')
    expect(wrapper.find('.page').text()).toBe('1')
  })
})

The results will look like this when executed:

Code Explanation

  • describe: Groups tests together.
  • it: Represents each test.
  • shallow: Renders React components.
  • Matchers: In the above code, matchers like toBeTruthy(), toBe() are used. Jest provides various matchers (https://jestjs.io/docs/using-matchers).
it("click right arrow", () => {
    const wrapper = shallow(<Counter />);
    wrapper.find(".next").simulate("click");
    expect(wrapper.find(".page").text()).toBe("1");

In the code snippet above, it tests that when the element with className ‘next’ in the Counter component is clicked, the text content of the element with className ‘page’ should be ‘1’.


Written by@Chaerin
Tech Blog📕

GitHubLinkedIn