- Published on
Testing Your React App
- Authors
- Name
In this blog post, we'll explore how to write tests for your React application using popular testing libraries such as Jest and React Testing Library.
Setting Up Your React Project
Before we dive into writing tests, let's set up a basic React project. Here is the structure of our project:
├── node_modules
├── public
│ ├── index.html
├── src
│ ├── components
│ │ ├── App.js
│ │ ├── App.test.js
│ ├── index.js
├── package.json
└── yarn.lock
Installing Testing Libraries
We will use Jest for running our tests and React Testing Library for testing our components. Let's install these libraries:
yarn add --dev jest @testing-library/react @testing-library/jest-dom
Writing Your First Test
Let's start by creating a simple component in src/components/App.js
.
import React from 'react'
const App = () => {
return (
<div>
<h1>Hello, World!</h1>
</div>
)
}
export default App
Now, let's write a test for the App
component in src/components/App.test.js
.
import React from 'react'
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import App from './App'
test('renders Hello, World!', () => {
render(<App />)
const headingElement = screen.getByText(/Hello, World!/i)
expect(headingElement).toBeInTheDocument()
})
Running Your Tests
To run your tests, you can use the yarn test
command:
yarn test
If everything is set up correctly, you should see an output indicating that the test passed.
PASS src/components/App.test.js
✓ renders Hello, World! (xms)
Testing User Interactions
React Testing Library makes it easy to test user interactions. Let's add a button to our App
component and test its functionality.
Update src/components/App.js
:
import React, { useState } from 'react'
const App = () => {
const [count, setCount] = useState(0)
return (
<div>
<h1>Hello, World!</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
)
}
export default App
Update src/components/App.test.js
:
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import App from './App'
test('renders Hello, World!', () => {
render(<App />)
const headingElement = screen.getByText(/Hello, World!/i)
expect(headingElement).toBeInTheDocument()
})
test('increments count when button is clicked', () => {
render(<App />)
const buttonElement = screen.getByText(/Increment/i)
fireEvent.click(buttonElement)
const countElement = screen.getByText(/Count: 1/i)
expect(countElement).toBeInTheDocument()
})
Testing Asynchronous Code
Sometimes, you need to test components that handle asynchronous operations. React Testing Library provides utilities for this as well. Let's add an asynchronous operation to our App
component.
Update src/components/App.js
:
import React, { useState } from 'react'
const App = () => {
const [count, setCount] = useState(0)
const [data, setData] = useState(null)
const fetchData = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1')
const result = await response.json()
setData(result)
}
return (
<div>
<h1>Hello, World!</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
<button onClick={fetchData}>Fetch Data</button>
{data && <p>{data.title}</p>}
</div>
)
}
export default App
Update src/components/App.test.js
:
import React from 'react'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import App from './App'
test('renders Hello, World!', () => {
render(<App />)
const headingElement = screen.getByText(/Hello, World!/i)
expect(headingElement).toBeInTheDocument()
})
test('increments count when button is clicked', () => {
render(<App />)
const buttonElement = screen.getByText(/Increment/i)
fireEvent.click(buttonElement)
const countElement = screen.getByText(/Count: 1/i)
expect(countElement).toBeInTheDocument()
})
test('fetches and displays data', async () => {
render(<App />)
const buttonElement = screen.getByText(/Fetch Data/i)
fireEvent.click(buttonElement)
const dataElement = await waitFor(() => screen.getByText(/delectus aut autem/i))
expect(dataElement).toBeInTheDocument()
})
Conclusion
Testing is a crucial part of developing robust React applications. By writing tests for your components, you can ensure that your application behaves as expected and catches bugs early in the development process. We covered the basics of writing and running tests in React using Jest and React Testing Library, including testing user interactions and asynchronous operations. Happy testing!