Моки и стабы — это два типа объектов, используемых в юнит-тестах для имитации работы зависимостей, с которыми взаимодействуют тестируемые компоненты. Они позволяют контролировать поведение зависимостей, изолировать тестируемую часть кода и эффективно проверять логику без необходимости интегрировать все реальные сервисы или внешние библиотеки. В контексте фреймворка Svelte они играют важную роль в тестировании компонентов и приложений, обеспечивая легкость в проведении тестов с моками и стабами.
Мок (от англ. mock) — это объект, который имитирует поведение реальной зависимости, но имеет заранее заданную логику или фиксированные данные. Моки используются для проверки взаимодействия компонента с другими частями системы, например, с API или сервисами.
В отличие от стабов, моки не просто заменяют часть функционала, но и позволяют проверять, как конкретный код взаимодействует с этим функционалом. Это означает, что моки могут отслеживать, были ли вызваны определённые методы, сколько раз, с какими параметрами и так далее.
Допустим, есть компонент, который зависит от сервиса для получения данных. Тестирование такого компонента без мока потребовало бы реального вызова API, что может быть не только медленно, но и нецелесообразно.
// Компонент, который зависит от API-сервиса
<script>
import { onMount } from 'svelte';
let data = [];
async function fetchData() {
const response = await fetch('https://api.example.com/data');
data = await response.json();
}
onMount(fetchData);
</script>
Для того чтобы протестировать этот компонент, можно создать мок для
функции fetch.
import { render } from '@testing-library/svelte';
import MyComponent from './MyComponent.svelte';
test('компонент получает данные через API', async () => {
// Мокаем функцию fetch
global.fetch = jest.fn().mockResolvedValue({
json: jest.fn().mockResolvedValue([{ id: 1, name: 'Test' }])
});
const { getByText } = render(MyComponent);
// Проверяем, что данные отобразились
await waitFor(() => getByText('Test'));
expect(fetch).toHaveBeenCalledWith('https://api.example.com/data');
});
В этом примере мы замещаем реальный вызов fetch на мок,
который сразу возвращает фиксированные данные. Это позволяет проверить
логику работы компонента без необходимости обращения к реальному
API.
Стаб (от англ. stub) — это объект, который имитирует поведение зависимой компоненты или функции, но в отличие от мока, стаб не отслеживает взаимодействие с ним. Его задача — вернуть заранее заданные данные или результат выполнения. В отличие от мока, стаб не предоставляет функционала для проверки вызовов методов, а только заменяет реальную зависимость.
Предположим, что в проекте используется модуль для работы с базой данных, и нужно протестировать компонент, который обращается к этому модулю. Вместо того чтобы использовать реальную базу данных, можно использовать стаб.
import { render } from '@testing-library/svelte';
import MyComponent from './MyComponent.svelte';
test('компонент взаимодействует с базой данных', async () => {
// Стабируем работу с базой данных
const db = {
getData: jest.fn().mockReturnValue([{ id: 1, name: 'Test' }])
};
const { getByText } = render(MyComponent, { props: { db } });
// Проверяем, что данные отобразились
await waitFor(() => getByText('Test'));
});
В данном случае стаб db.getData всегда возвращает
фиксированный результат, что позволяет протестировать логику компонента,
не взаимодействуя с реальной базой данных.
Хотя моки и стабы имеют сходную цель — заменить реальные зависимости в тестах, они обладают различиями, которые могут определять выбор в зависимости от ситуации:
Поведение:
Тестируемые аспекты:
Использование:
В Svelte тестах, как и в других приложениях на JavaScript, моки и
стабы можно использовать для замены внешних зависимостей, таких как
API-запросы, работа с базами данных или любые другие сервисы, которые
сложно тестировать в условиях реального выполнения. С помощью
инструментов, таких как jest или sinon, можно
удобно мокаить или стабировать функции.
Пример мокирования компонента с внешним сервисом:
import { render, fireEvent } from '@testing-library/svelte';
import MyComponent from './MyComponent.svelte';
// Мокаем функцию из внешнего сервиса
jest.mock('../services/api', () => ({
fetchData: jest.fn().mockResolvedValue([{ id: 1, name: 'Test' }])
}));
test('компонент получает данные при клике', async () => {
const { getByText } = render(MyComponent);
// Симулируем клик, который должен инициировать запрос
const button = getByText('Загрузить данные');
await fireEvent.click(button);
// Проверяем, что данные отобразились
await waitFor(() => getByText('Test'));
});
Этот пример показывает, как мокаем внешний сервис с помощью
jest.mock и проверяем поведение компонента при
взаимодействии с ним.
Моки и стабы играют важную роль в тестировании компонентов и приложений на Svelte, позволяя изолировать код и проверять его логику без необходимости взаимодействия с внешними сервисами. Они помогают сделать тесты более стабильными, быстрыми и предсказуемыми, что особенно важно при работе с большими и сложными приложениями.