Настройка DOM окружения

Jest, как инструмент для тестирования JavaScript, изначально ориентирован на выполнение юнит-тестов и предоставляет гибкие возможности для тестирования кода, работающего с DOM. Веб-приложения и интерфейсы часто взаимодействуют с элементами на странице, поэтому настройка DOM окружения для корректного выполнения тестов является важной частью процесса.

Зачем нужно настроить DOM в Jest?

По умолчанию Jest использует Node.js для выполнения тестов, что означает отсутствие реального DOM, как это происходит в браузере. Однако многие тесты, особенно те, которые касаются работы с UI, требуют взаимодействия с DOM, например, манипуляции с элементами страницы или обработка событий. Jest предлагает несколько подходов к настройке окружения, чтобы воспроизвести поведение настоящего браузера.

Использование jsdom

Для создания тестового окружения, максимально приближенного к браузерному, Jest использует библиотеку jsdom. Она представляет собой реализацию веб-стандартов, таких как window, document, navigator и другие глобальные объекты, используемые в браузере, в среде Node.js. Это позволяет тестировать взаимодействие с DOM без необходимости использовать реальные браузеры.

jsdom автоматически настраивается при установке Jest, и тесты выполняются с использованием виртуального DOM, предоставляемого этим инструментом. С его помощью можно манипулировать элементами, вызывать события и проверять их поведение, как если бы тесты выполнялись в реальной браузерной среде.

Пример работы с jsdom

test('проверка создания элемента', () => {
  const div = document.createElement('div');
  div.textContent = 'Привет, мир!';
  document.body.appendChild(div);

  const foundElement = document.querySelector('div');
  expect(foundElement).not.toBeNull();
  expect(foundElement.textContent).toBe('Привет, мир!');
});

В этом примере создается элемент div, добавляется на страницу и проверяется, что он появился в DOM и содержит ожидаемый текст.

Изменение конфигурации jsdom

Хотя jest автоматически предоставляет jsdom для работы с DOM, иногда нужно настроить его параметры, например, установить параметры окна или изменить поведение специфических объектов. Это можно сделать, добавив настройку в конфигурацию Jest.

Для этого в файл конфигурации jest.config.js можно добавить свойство testEnvironment, которое позволяет выбирать различные окружения для выполнения тестов. Для использования jsdom нужно указать его явно.

Пример конфигурации:

module.exports = {
  testEnvironment: 'jsdom', // по умолчанию jsdom используется автоматически
};

Если необходимо изменить конкретные параметры jsdom, например, глобальные переменные или настройки, можно использовать хук setupFiles. В этом файле можно настроить начальные условия для каждого теста.

Пример использования:

module.exports = {
  setupFiles: ['./jest.setup.js'],
};

В файле jest.setup.js можно настроить, например, глобальные переменные или моки:

global.customConfig = { theme: 'dark' };

Мокирование DOM-методов

В процессе тестирования может возникнуть необходимость замены реальных методов DOM на моки. Jest предоставляет функцию jest.spyOn, с помощью которой можно следить за вызовами методов DOM.

Пример:

test('проверка мокирования события', () => {
  const button = document.createElement('button');
  button.textContent = 'Нажми меня';
  document.body.appendChild(button);

  const mockHandler = jest.fn();
  button.addEventListener('click', mockHandler);

  button.click();

  expect(mockHandler).toHaveBeenCalledTimes(1);
});

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

Мокирование объектов, не поддерживаемых в jsdom

Иногда тестируемый код может зависеть от специфических объектов, которые не поддерживаются в jsdom, например, API браузера для работы с геолокацией или другими встроенными сервисами. В этих случаях можно воспользоваться моками, чтобы симулировать нужное поведение.

Пример мокирования геолокации:

beforeAll(() => {
  global.navigator.geolocation = {
    getCurrentPosition: jest.fn().mockImplementation((success) =>
      success({ coords: { latitude: 50, longitude: 30 } })
    ),
  };
});

test('проверка геолокации', () => {
  navigator.geolocation.getCurrentPosition((position) => {
    expect(position.coords.latitude).toBe(50);
    expect(position.coords.longitude).toBe(30);
  });
});

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

Использование Enzyme для сложных манипуляций с DOM

Хотя Jest и предоставляет базовые средства для работы с DOM, для более сложных манипуляций, таких как рендеринг компонентов React, может быть полезным использование библиотеки Enzyme. Enzyme предоставляет утилиты для глубокого рендеринга, монтирования и манипуляции компонентами, которые в свою очередь работают с виртуальным DOM.

Пример использования Enzyme с Jest:

import { shallow } from 'enzyme';
import MyComponent from './MyComponent';

test('проверка рендера компонента', () => {
  const wrapper = shallow(<MyComponent />);
  expect(wrapper.find('button').text()).toBe('Нажми меня');
});

Enzyme предоставляет гибкие возможности для тестирования компонентов и их взаимодействия с DOM, что особенно полезно при тестировании React-приложений.

Завершающие настройки

В большинстве случаев, настройка DOM окружения в Jest сводится к использованию jsdom и простому мокации специфических браузерных API, если это необходимо. Основное внимание стоит уделить правильной настройке тестового окружения, чтобы оно максимально соответствовало реальному браузеру, и использованию инструментов для работы с виртуальным DOM.

Понимание тонкостей настройки и работы с DOM в Jest позволяет писать качественные и стабильные тесты для взаимодействующих с DOM приложений.