Моки и стабы

В контексте разработки на FAST Element моки и стабы играют ключевую роль при тестировании компонентов. Они позволяют изолировать логику компонента, имитировать внешние зависимости и контролировать поведение без реального взаимодействия с DOM или API.

Различие между моками и стабами

  • Стаб (stub) — это заглушка, объект или функция, которая предоставляет заранее определённый ответ на вызовы, не выполняя реальной логики. Стабы используются для предсказуемости тестов и проверки того, как компонент реагирует на различные данные.
  • Мок (mock) — это расширение стаба, которое не только возвращает данные, но и записывает, как и с какими аргументами была вызвана функция. Моки позволяют проверять взаимодействия, количество вызовов и порядок их выполнения.

Пример: если компонент запрашивает данные с сервера, стаб может просто возвращать фиктивный объект, а мок позволит проверить, что метод запроса был вызван с правильными параметрами.

Создание стаба для FAST компонента

FAST Element строится на базе Web Components, поэтому компоненты обычно наследуют FASTElement. Для стаба нужно изолировать зависимости компонента.

import { FASTElement, html, css } from "@microsoft/fast-element";

class UserCard extends FASTElement {
    static template = html`<div>${x => x.name}</div>`;
    static styles = css`div { font-weight: bold; }`;

    name = '';

    async fetchUser() {
        const response = await fetch(`/api/user`);
        this.name = await response.json().then(data => data.name);
    }
}

// Создание стаба fetch
const fetchStub = async () => ({ json: async () => ({ name: 'Тестовый пользователь' }) });

const userCard = new UserCard();
userCard.fetchUser = fetchStub; // замена метода на стаб
await userCard.fetchUser();
console.log(userCard.name); // "Тестовый пользователь"

В этом примере реальный сетевой вызов заменён на стаб, который возвращает фиксированные данные.

Использование моков для проверки взаимодействий

Моки позволяют контролировать количество вызовов метода и параметры. Для компонентов FAST это особенно полезно при тестировании событий и реактивных свойств.

import { FASTElement, html } from "@microsoft/fast-element";

class CounterButton extends FASTElement {
    static template = html`<button @click="${x => x.increment()}">Нажми</button>`;
    count = 0;

    increment() {
        this.count++;
    }
}

// Создание мока функции
const incrementMock = jest.fn();
const button = new CounterButton();
button.increment = incrementMock;

// Симуляция клика
button.$emit('click');
button.increment();
button.increment();

// Проверка вызовов
console.log(incrementMock.mock.calls.length); // 2

Мок фиксирует все вызовы метода increment, позволяя убедиться в корректном поведении компонента.

Комбинирование моков и стабов

В реальных проектах часто требуется комбинация. Например, компонент отправляет данные на сервер и обновляет внутреннее состояние. Для теста можно:

  1. Стабировать серверный запрос, чтобы не зависеть от реальной сети.
  2. Мокировать методы компонента, чтобы проверить, сколько раз и с какими аргументами они были вызваны.
const apiStub = async () => ({ status: 200 });
const updateMock = jest.fn();

component.sendData = apiStub;
component.updateUI = updateMock;

await component.sendData();
component.updateUI();

console.assert(updateMock.mock.calls.length === 1);

Специфика работы с реактивными свойствами FAST

FAST Element использует наблюдаемые свойства, которые автоматически обновляют DOM при изменении значений. При тестировании с моками и стабами важно учитывать:

  • Присвоение значения свойства должно быть синхронизировано с DOM через await FASTElement.nextTick().
  • Стабы можно использовать для имитации источников данных, а моки — для проверки реакции на изменение свойств.
import { FASTElement, html, nextTick } from "@microsoft/fast-element";

class MessageDisplay extends FASTElement {
    static template = html`<p>${x => x.message}</p>`;
    message = '';
}

const messageStub = 'Привет, тест!';
const component = new MessageDisplay();
component.message = messageStub;

await nextTick(); // обновление DOM
console.log(component.shadowRoot.innerHTML.includes(messageStub)); // true

Практические рекомендации

  • Моки лучше использовать для проверки взаимодействий между методами и компонентами.
  • Стабы эффективны для изоляции внешних зависимостей и создания предсказуемой среды.
  • Комбинация моков и стабов позволяет тестировать сложные сценарии без реальных вызовов API или сложного состояния приложения.
  • В тестах FAST Element важно учитывать асинхронность реактивных обновлений DOM, используя nextTick() для синхронизации.

Моки и стабы обеспечивают точное управление поведением компонентов и помогают писать надежные, предсказуемые тесты для сложных интерфейсов на FAST Element.