Haunted — это библиотека для создания веб-компонентов на основе функционального подхода и хуков, вдохновлённая React. Одной из важных задач при разработке сложных компонентов является тестирование. В этом контексте мокирование хуков становится необходимым инструментом для изоляции компонентов и контроля их поведения.
Мокирование хуков в Haunted опирается на несколько ключевых моментов:
Изоляция логики компонента Хуки инкапсулируют состояние и побочные эффекты. Для корректного тестирования важно заменить реальную реализацию хуков на заглушки (mocks), которые возвращают предсказуемые значения.
Контроль состояния Моки позволяют задавать начальное состояние и отслеживать изменения без реального рендеринга сложных структур или сетевых запросов.
Предсказуемость побочных эффектов Вместо
выполнения useEffect, который может инициировать сетевые
запросы или анимации, мок возвращает заранее определённое
поведение.
import { useCounter } from './hooks';
jest.mock('./hooks');
useCounter.mockImplementation(() => {
return [42, () => {}]; // фиксированное значение состояния и пустая функция обновления
});
Такой подход позволяет тестировать компонент без выполнения реальной логики состояния.
export const useToggle = () => {
const [value, setValue] = useState(false);
const toggle = () => setValue(!value);
return [value, toggle];
};
// В тесте
import * as hooks from './component';
jest.spyOn(hooks, 'useToggle').mockReturnValue([true, () => {}]);
Такой способ сохраняет доступ к исходному компоненту, но позволяет контролировать поведение состояния.
Haunted предоставляет базовые хуки: useState,
useEffect, useRef, useReducer и
другие. Для тестирования компонентов часто необходимо мокировать их
стандартное поведение.
jest.spyOn(Haunted, 'useState').mockImplementation((initial) => [initial, () => {}]);
jest.spyOn(Haunted, 'useEffect').mockImplementation(() => {});
jest.spyOn(Haunted, 'useReducer').mockImplementation((reducer, initial) => [initial, jest.fn()]);
import { html, render } from 'lit';
import { MyComponent } from './my-component';
import * as hooks from './hooks';
jest.spyOn(hooks, 'useCounter').mockReturnValue([10, () => {}]);
const container = document.createElement('div');
render(html`<${MyComponent}></${MyComponent}>`, container);
expect(container.textContent).toContain('10');
const mockSet = jest.fn();
jest.spyOn(hooks, 'useCounter').mockReturnValue([0, mockSet]);
// эмулируем клик
container.querySelector('button').click();
expect(mockSet).toHaveBeenCalled();
useEffect для загрузки данных, можно мокировать
fetch или API и одновременно отключить эффект:jest.spyOn(Haunted, 'useEffect').mockImplementation((fn) => fn());
global.fetch = jest.fn().mockResolvedValue({ json: () => ({ id: 1 }) });
jest.resetAllMocks() для предотвращения нежелательных
побочных эффектов между тестами.Мокирование хуков в Haunted позволяет тестировать компоненты независимо от их внутренней логики, контролировать состояние и побочные эффекты, а также создавать предсказуемую среду для юнит-тестирования. Грамотно организованные моки повышают надёжность тестов и ускоряют процесс разработки сложных веб-компонентов.