This article explores using Jest, a Facebook-maintained testing framework, to test React components and plain JavaScript functions. We'll start with simple JavaScript functions before moving to React-specific features. Jest isn't exclusively for React; it's versatile enough for any JavaScript application. However, its features are particularly useful for UI testing, making it ideal for React.
Key Points:
A Sample Todo Application:
A small todo application (available on GitHub and as a live demo) serves as our test subject. It's built using ES2015, webpack, and Babel. The core logic resides in app/state-functions.js
, containing pure functions (toggleDone
, addTodo
, deleteTodo
) that manage application state. These functions are analogous to Redux reducers.
Test-Driven Development (TDD):
While TDD (writing tests before code) has advantages, the approach is often a matter of personal preference. For React components, writing components first and then adding tests is often practical.
Introducing Jest:
Jest, significantly improved by Facebook, offers a streamlined setup compared to other frameworks. Its parallel test execution and watch mode significantly improve testing speed and efficiency. It includes JSDom for browser-like testing within Node.js and supports asynchronous tests, mocking, spies, and stubs.
Installation and Configuration:
Install necessary packages:
npm install --save-dev jest babel-jest @babel/core @babel/preset-env @babel/preset-react
Ensure a babel.config.js
file is present (example provided in the original article). Jest expects tests in a __tests__
directory (or files ending in .test.js
or .spec.js
).
Testing Business Logic:
A simple test for toggleDone
demonstrates Jest's usage:
import { toggleDone } from '../app/state-functions'; test('toggleDone completes an incomplete todo', () => { const startState = [{ id: 1, done: false, text: 'Buy Milk' }]; const finState = toggleDone(startState, 1); expect(finState).toEqual([{ id: 1, done: true, text: 'Buy Milk' }]); });
toEqual
is used for object/array comparison, while toBe
is for primitive types. Jest's watch mode (npm test -- --watch
or jest --watch
) automatically reruns tests on file changes. A similar test for deleteTodo
is also shown in the original article.
Testing React Components:
Testing React components often involves less comprehensive testing than business logic. Enzyme (or React Testing Library, as recommended by the React team) simplifies this process. Install Enzyme and the appropriate adapter:
npm install --save-dev jest babel-jest @babel/core @babel/preset-env @babel/preset-react
Create setup-tests.js
to configure Enzyme:
import { toggleDone } from '../app/state-functions'; test('toggleDone completes an incomplete todo', () => { const startState = [{ id: 1, done: false, text: 'Buy Milk' }]; const finState = toggleDone(startState, 1); expect(finState).toEqual([{ id: 1, done: true, text: 'Buy Milk' }]); });
Configure Jest in package.json
to use setup-tests.js
:
npm install --save-dev enzyme @wojtekmaj/enzyme-adapter-react-17
A test for the Todo
component rendering is shown, using mount
to render and find
to locate elements. A subsequent test uses jest.fn()
to create a spy function and simulate('click')
to trigger an event, verifying function calls with toBeCalledWith
.
Conclusion:
Jest's speed, watch mode, and expressive API make it a powerful testing framework. The article concludes with a summary of its benefits and further reading suggestions, along with FAQs addressing common questions about testing React components with Jest. The FAQs cover render
, React Test Renderer, testing components with props, and testing functions within components.
The above is the detailed content of How to Test React Components Using Jest. For more information, please follow other related articles on the PHP Chinese website!