Напишите эффективные и надежные тесты для ваших приложений React, используя Jest
Тестирование — важнейший аспект разработки программного обеспечения, который помогает нам гарантировать надежность, удобство сопровождения и эффективность нашего кода. React, одна из самых популярных библиотек JavaScript для создания пользовательских интерфейсов, имеет динамичную экосистему с множеством инструментов и библиотек, помогающих в написании тестов. Jest — одна из таких сред тестирования, которая в последние годы приобрела огромную популярность.
Jest, разработанный Facebook, представляет собой мощную и гибкую среду тестирования, которая позволяет разработчикам писать тесты как для простых, так и для сложных компонентов React. В этой статье мы рассмотрим, как вы можете протестировать свои компоненты React с помощью Jest, а также поделимся практическими примерами кода, которые помогут вам сразу приступить к работе.
Настройка Jest в вашем проекте React
Чтобы начать работу с Jest, вам сначала нужно установить его и настроить в своем проекте React. Вы можете сделать это, выполнив следующую команду:
npm install — save-dev jest babel-jest @babel/preset-env @babel/preset-react react-test-renderer
Затем создайте файл .babelrc в корне вашего проекта и добавьте следующую конфигурацию:
{ "presets": ["@babel/preset-env", "@babel/preset-react"] }
Наконец, добавьте следующий тестовый скрипт в ваш package.json:
{ "scripts": { "test": "jest" } }
Теперь вы готовы начать писать тесты для своих компонентов React!
Начнем с тестирования простого компонента React. Рассмотрим следующий компонент «Счетчик», который позволяет пользователям увеличивать и уменьшать значение:
import React, { useState } from 'react'; export const Counter = () => { const [count, setCount] = useState(0); return ( <div> <p>Count: {count}</p> <button onClick={() => setCount(count + 1)}>Increment</button> <button onClick={() => setCount(count - 1)}>Decrement</button> </div> ); };
Чтобы протестировать этот компонент, мы создадим файл Counter.test.js вместе с файлом компонента и напишем следующий тест:
import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import { Counter } from './Counter'; test('Counter increments and decrements count', () => { const { getByText } = render(<Counter />); const countElement = getByText(/count:/i); const incrementButton = getByText(/increment/i); const decrementButton = getByText(/decrement/i); expect(countElement.textContent).toBe('Count: 0'); fireEvent.click(incrementButton); expect(countElement.textContent).toBe('Count: 1'); fireEvent.click(decrementButton); expect(countElement.textContent).toBe('Count: 0'); });
В этом тесте мы используем библиотеку @testing-library/react для рендеринга компонента Счетчик и взаимодействия с его элементами. Сначала мы проверяем, равен ли начальный счетчик 0, затем моделируем событие щелчка на кнопках увеличения и уменьшения и подтверждаем, изменяется ли счетчик, как ожидалось.
Тестирование компонента с реквизитами
Теперь давайте протестируем компонент React, который получает свойства. Рассмотрим следующий компонент «Приветствие»:
import React from 'react'; export const Greeting = ({ name }) => { return <p>Hello, {name}!</p>; };
Чтобы протестировать этот компонент, мы создадим файл `Greeting.test.js` и напишем следующий тест:
import React from 'react'; import { render } from '@testing-library/react'; import { Greeting } from './Greeting'; test('Greeting renders the correct text with given name', () => { const { getByText } = render(<Greeting name="John" />); expect(getByText(/hello, john!/i)).toBeInTheDocument(); });
В этом тесте мы визуализируем компонент «Приветствие» с реквизитом «имя» и утверждаем, что отображаемый текст включает предоставленное имя.
Тестирование компонента с состоянием и useEffect
Давайте протестируем более сложный компонент, использующий состояние и хук useEffect. Предположим, у нас есть компонент «Пользователь», который извлекает пользовательские данные из API и отображает их:
import React, { useState, useEffect } from 'react'; export const User = ({ userId }) => { const [user, setUser] = useState(null); useEffect(() => { const fetchUser = async () => { const res = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`); const data = await res.json(); setUser(data); }; fetchUser(); }, [userId]); return ( <div> {user ? ( <p>{user.name}</p> ) : ( <p>Loading...</p> )} </div> ); };
Примечание. В этом примере мы используем API-заполнитель JSON — забавный, бесплатный и простой в использовании API для тестирования, разработки и обучения (https://jsonplaceholder.typicode.com/ )
Для этого компонента нам нужно смоделировать вызов API, чтобы обеспечить контролируемую среду тестирования. Мы создадим файл User.test.js и напишем следующий тест:
import React from 'react'; import { render, waitFor } from '@testing-library/react'; import { User } from './User'; // Mock API call global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve({ name: 'John Doe' }), }), ); test('User component fetches and displays user data', async () => { const { getByText } = render(<User userId={1} />); expect(getByText(/loading.../i)).toBeInTheDocument(); await waitFor(() => expect(getByText(/john doe/i)).toBeInTheDocument()); expect(fetch).toHaveBeenCalledTimes(1); });
В этом тесте мы имитируем функцию `fetch`, чтобы вернуть разрешенный промис с желаемым объектом пользователя. Затем мы визуализируем компонент Пользователь и проверяем, отображается ли загружаемый текст изначально. Используя функцию `waitFor` из `@testing-library/react`, мы ждем, пока пользовательские данные будут получены и отображены. Наконец, мы гарантируем, что функция `fetch` вызывается один раз.
Заключение
В этой статье мы рассмотрели, как тестировать компоненты React с помощью Jest, охватив различные сценарии, такие как тестирование компонентов с состоянием, реквизитами и useEffect. Следуя этим примерам, вы можете создавать надежные тесты для своих приложений React, гарантируя, что ваши компоненты ведут себя так, как ожидается, и упрощая поддержку и рефакторинг вашего кода в будущем.
Помните, что тестирование — это неотъемлемая часть разработки программного обеспечения, и затраты времени на изучение и внедрение правильных методов тестирования окупятся в долгосрочной перспективе. Удачного тестирования!