Test React components

Use Jest andreact-testing-library

The easiest way to start testing React components is to perform snapshot testing, which is a testing technique that allows you to isolate test components.

If you are familiar with testing software, it is like unit testing your classes: you test the functionality of each component.

I assume you created a React applicationcreate-react-app, Already attachedjokeAfter installation, we will need the test package.

Let's start with a simple test. CodeSandbox is a good environment for experimentation. Start with the React sandbox, then create aApp.jsA componentcomponentsFolder and add aApp.test.jsfile.

import React from 'react'

export default function App() { return ( <div className=“App”> <h1>Hello CodeSandbox</h1> <h2>Start editing to see some magic happen!</h2> </div> ) }

Our first test is stupid:

test('First test', () => {
  expect(true).toBeTruthy()
})

When CodeSandbox detects the test files, it will automatically run them for you, and you can click the "Test" button at the bottom of the view to display the test results:

A test file can contain multiple tests:

Now let's do some more useful operations to actually test React components. Now we only have the App, which doesn't do anything really useful, so let's first set up the environment with a small app with more features: the counter app we built before. If you skip it, you can go back and read how we built it, but for ease of reference, I add it here again.

It has only 2 components: App and Button. createApp.jsfile:

import React, { useState } from 'react'
import Button from './Button'

const App = () => { const [count, setCount] = useState(0)

const incrementCount = increment => { setCount(count + increment) }

return ( <div> <Button increment={1} onClickFunction={incrementCount} /> <Button increment={10} onClickFunction={incrementCount} /> <Button increment={100} onClickFunction={incrementCount} /> <Button increment={1000} onClickFunction={incrementCount} /> <span>{count}</span> </div> ) }

export default App

withButton.jsfile:

import React from 'react'

const Button = ({ increment, onClickFunction }) => { const handleClick = () => { onClickFunction(increment) } return <button onClick={handleClick}>+{increment}</button> }

export default Button

We will usereact-testing-library, This is a great help because it allows us to check the output of each component and apply events to them. You can read more about it belowhttps://github.com/kentcdodds/react-testing-libraryOr watchThis video.

Let's test the Button component first.

We start with importrenderwithfireEventFromreact-testing-library, Two helpers. The first one lets us render JSX. The second one lets us emit events on the component.

CreateButton.test.jsAnd put it in the same folder as thatButton.js.

import React from 'react'
import { render, fireEvent } from 'react-testing-library'
import Button from './Button'

Buttons are used in the application to receive click events, and then they are called and passed toonClickFunctionpillar. We add acountVariable, and then we create a function that increments it:

let count

const incrementCount = increment => { count += increment }

Now start the actual test. We first initialize count to 0, and then render one+1 ButtonComponent passed1ToincrementAnd ourincrementCountPlay a roleonClickFunction.

Then we get the content of the first child of the component and check its output+1.

Then, we continue to click the button and check if the count changes from 0 to 1:

test('+1 Button works', () => {
  count = 0
  const { container } = render(
    <Button increment={1} onClickFunction={incrementCount} />
  )
  const button = container.firstChild
  expect(button.textContent).toBe('+1')
  expect(count).toBe(0)
  fireEvent.click(button)
  expect(count).toBe(1)
})

Similarly, we test a +100 button, this time check whether the output is+100 and the button click increments the count of 100.

test('+100 Button works', () => {
  count = 0
  const { container } = render(
    <Button increment={100} onClickFunction={incrementCount} />
  )
  const button = container.firstChild
  expect(button.textContent).toBe('+100')
  expect(count).toBe(0)
  fireEvent.click(button)
  expect(count).toBe(100)
})

Now let's test the App component. It displays 4 buttons and results on the page. We can check each button and click on them multiple times to see if the result increases:

import React from 'react'
import { render, fireEvent } from 'react-testing-library'
import App from './App'

test(‘App works’, () => { const { container } = render(<App />) console.log(container) const buttons = container.querySelectorAll(‘button’)

expect(buttons[0].textContent).toBe(’+1’) expect(buttons[1].textContent).toBe(’+10’) expect(buttons[2].textContent).toBe(’+100’) expect(buttons[3].textContent).toBe(’+1000’)

const result = container.querySelector(‘span’) expect(result.textContent).toBe(‘0’) fireEvent.click(buttons[0]) expect(result.textContent).toBe(‘1’) fireEvent.click(buttons[1]) expect(result.textContent).toBe(‘11’) fireEvent.click(buttons[2]) expect(result.textContent).toBe(‘111’) fireEvent.click(buttons[3]) expect(result.textContent).toBe(‘1111’) fireEvent.click(buttons[2]) expect(result.textContent).toBe(‘1211’) fireEvent.click(buttons[1]) expect(result.textContent).toBe(‘1221’) fireEvent.click(buttons[0]) expect(result.textContent).toBe(‘1222’) })

Check the code running on this CodeSandbox:https://codesandbox.io/s/pprl4y0wq

Download mine for freeResponse Handbook


More response tutorials: