Глобальные объекты: window, document, navigator

При тестировании React-компонентов с помощью React Testing Library важно понимать, как работают основные глобальные объекты JavaScript, такие как window, document и navigator. Эти объекты предоставляют API для взаимодействия с браузером, и их поведение может оказывать влияние на тесты.

window

Объект window представляет собой глобальный объект, который используется для работы с окружением браузера. В контексте тестирования React-компонентов он играет важную роль, так как все браузерные события, таймеры и DOM-операции зависят от него. Например, такие методы, как setTimeout, setInterval и clearInterval, принадлежат именно объекту window.

React Testing Library использует объект window для имитации и тестирования различных сценариев работы с браузером. Например, события, такие как resize, scroll или любые пользовательские действия, могут быть симулированы через этот объект. Важно понимать, что React Testing Library активно взаимодействует с этим объектом, делая возможным манипулирование окнами, прокруткой и взаимодействием с элементами на странице.

Пример тестирования с использованием объекта window:

import { render, screen, fireEvent } from '@testing-library/react';
import MyComponent from './MyComponent';

test('изменение ширины окна вызывает событие', () => {
  render(<MyComponent />);
  
  // Изменение размера окна
  window.innerWidth = 500;
  window.dispatchEvent(new Event('resize'));
  
  const element = screen.getByText(/событие resize/);
  expect(element).toBeInTheDocument();
});

В данном примере имитируется событие изменения размера окна, что вызывает перерисовку компонента и проверку его поведения.

document

Объект document представляет собой интерфейс взаимодействия с DOM-деревом. Он является основным объектом для поиска, изменения и манипулирования элементами в DOM. React Testing Library использует document для того, чтобы абстрагироваться от деталей реализации и предоставить более удобный API для тестирования.

При рендеринге компонента с помощью React Testing Library, объект document становится доступным для поиска элементов, добавленных в DOM. Все методы поиска, такие как getByText, getByRole и другие, используют именно объект document для нахождения элементов на странице.

Пример использования объекта document для тестирования компонентов:

import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';

test('поиск элемента в документе', () => {
  render(<MyComponent />);
  
  const element = screen.getByText(/тестовое содержимое/);
  expect(element).toBeInTheDocument();
});

В этом примере метод screen.getByText использует document для поиска элемента с текстом “тестовое содержимое” в DOM.

Объект navigator предоставляет информацию о браузере и операционной системе пользователя. В контексте тестирования, navigator часто используется для проверки свойств, таких как тип устройства, язык или поддержка определённых возможностей (например, наличие определённого браузера).

React Testing Library может использовать объект navigator для симуляции поведения различных устройств или браузеров, что помогает в тестировании адаптивности компонентов.

Пример использования объекта navigator для тестирования функционала, связанного с устройствами:

import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';

test('проверка работы с мобильным устройством', () => {
  // Мокаем свойство userAgent
  Object.defineProperty(window.navigator, 'userAgent', {
    value: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/537.36 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1',
  });

  render(<MyComponent />);
  
  const element = screen.getByText(/мобильный интерфейс/);
  expect(element).toBeInTheDocument();
});

В данном примере мы мокаем свойство userAgent объекта navigator, чтобы симулировать работу на мобильном устройстве, и проверяем, как компонент реагирует на эти изменения.

Взаимодействие с глобальными объектами в тестах

React Testing Library позволяет эмулировать поведение браузера через взаимодействие с глобальными объектами, такими как window, document и navigator. Чтобы сделать тесты более приближенными к реальному пользователю, важно правильно использовать эти объекты. Они могут быть использованы для симуляции различных сценариев, таких как изменение размеров экрана, проверка доступности элементов в DOM или эмуляция работы на разных устройствах.

При написании тестов следует учитывать, что некоторые глобальные объекты могут быть изменены в ходе выполнения тестов. Например, при изменении значения window.innerWidth или при мокации navigator.userAgent важно, чтобы изменения были восстановлены после завершения тестов, чтобы избежать побочных эффектов в других тестах.

Советы по использованию глобальных объектов в тестах

  1. Чистота состояния. Убедитесь, что изменения, которые вы вносите в глобальные объекты, не влияют на другие тесты. Для этого можно использовать методы восстановления значений после тестов (например, через beforeEach и afterEach).

  2. Мокация объектов. Для тестирования специфических сценариев, например, работы на мобильных устройствах или с определённым браузером, может потребоваться мокать navigator или window. Используйте такие методы, как Object.defineProperty, чтобы изменить поведение этих объектов в рамках теста.

  3. Использование событий. Глобальные объекты window и document часто используются для диспатча событий. Важно помнить, что React Testing Library предоставляет возможность для эмуляции этих событий, что позволяет проверять реакции компонентов на них.

  4. Проверка на разных устройствах. С помощью navigator можно проверять, как компоненты реагируют на различные устройства, например, меняя свойство userAgent для имитации мобильного устройства или планшета.

Правильное использование глобальных объектов при тестировании React-компонентов позволяет создавать более надёжные и реалистичные тесты, которые могут имитировать реальные условия работы браузера и устройства пользователя.