<textarea> в React используется для ввода
многострочного текста и часто управляется через контролируемые
компоненты, где значение хранится в состоянии. Тестирование
<textarea> в React Testing Library требует понимания
взаимодействия с DOM и событий ввода.
<textarea>В React Testing Library для работы с <textarea>
применяются те же подходы, что и с <input>, но с
учётом особенностей многострочного текста.
Основные моменты:
<textarea> хранится в атрибуте
value.change.getByRole, getByLabelText или
getByPlaceholderText.Пример:
import { render, screen, fireEvent } from '@testing-library/react';
import React, { useState } from 'react';
function CommentBox() {
const [comment, setComment] = useState('');
return (
<textarea
value={comment}
onCha nge={(e) => setComment(e.target.value)}
placeholder="Введите комментарий"
/>
);
}
test('ввод текста в textarea', () => {
render(<CommentBox />);
const textarea = screen.getByPlaceholderText('Введите комментарий');
fireEvent.change(textarea, { target: { value: 'Новый комментарий' } });
expect(textarea.value).toBe('Новый комментарий');
});
<textarea>1. getByRole
<textarea> имеет роль textbox, что
позволяет находить элемент через:
const textarea = screen.getByRole('textbox');
Если на странице несколько текстовых полей, можно использовать имя
(name или aria-label):
const textarea = screen.getByRole('textbox', { name: /комментарий/i });
2. getByLabelText
Для связанного с <label>
<textarea>:
<label htmlFor="comment">Комментарий</label>
<textarea id="comment" />
Тогда тест:
const textarea = screen.getByLabelText('Комментарий');
3. getByPlaceholderText
Полезно, когда <textarea> имеет
placeholder:
const textarea = screen.getByPlaceholderText('Введите комментарий');
Основные способы изменения значения
<textarea>:
1. fireEvent.change
fireEvent.change(textarea, { target: { value: 'Тестовый текст' } });
2. userEvent.type (предпочтительный для
имитации пользовательского ввода)
import userEvent from '@testing-library/user-event';
await userEvent.type(textarea, 'Тестовый текст');
userEvent.type имитирует ввод построчно, триггерит
события keydown, keypress, input
и keyup, что делает тест более приближенным к реальному
поведению пользователя.
В <textarea> строки разделяются символом новой
строки \n. При тестировании важно учитывать это:
const multilineText = 'Первая строка\nВторая строка\nТретья строка';
fireEvent.change(textarea, { target: { value: multilineText } });
expect(textarea.value).toBe(multilineText);
Контролируемый <textarea> обновляет значение
состояния компонента. Проверка часто включает:
textarea.value)function CommentBoxWithPreview() {
const [comment, setComment] = useState('');
return (
<>
<textarea value={comment} onCha nge={(e) => setComment(e.target.value)} />
<div data-testid="preview">{comment}</div>
</>
);
}
test('textarea обновляет превью', async () => {
render(<CommentBoxWithPreview />);
const textarea = screen.getByRole('textbox');
const preview = screen.getByTestId('preview');
fireEvent.change(textarea, { target: { value: 'Тест' } });
expect(preview.textContent).toBe('Тест');
});
Иногда важно проверить поведение при фокусе или потере фокуса:
textarea.focus();
expect(document.activeElement).toBe(textarea);
textarea.blur();
expect(document.activeElement).not.toBe(textarea);
userEvent также поддерживает tab() для
навигации по элементам.
Для <textarea> с валидацией можно тестировать
отображение ошибок:
function CommentForm() {
const [comment, setComment] = useState('');
const [error, setError] = useState('');
const handleSubmit = () => {
if (!comment) setError('Комментарий обязателен');
};
return (
<>
<textarea value={comment} onCha nge={(e) => setComment(e.target.value)} />
{error && <span role="alert">{error}</span>}
<button onCl ick={handleSubmit}>Отправить</button>
</>
);
}
test('отображает ошибку при пустом комментарии', () => {
render(<CommentForm />);
const button = screen.getByText('Отправить');
fireEvent.click(button);
expect(screen.getByRole('alert').textContent).toBe('Комментарий обязателен');
});
<textarea>userEvent.type для
имитации реального пользовательского ввода.textarea.value, а не
напрямую через состояние компонента.\n.getByRole,
getByLabelText) для надежности тестов.Эти подходы обеспечивают комплексное покрытие тестами
<textarea> и гарантируют корректную проверку
пользовательского взаимодействия, реактивного состояния и отображения
ошибок в приложениях на React.