Slim.js предоставляет мощный инструмент для создания легковесных веб-компонентов с декларативным синтаксисом и реактивным состоянием. Одной из ключевых задач при разработке приложений на Slim.js является тестирование компонентов. Для этого широко применяются моки и стабы, позволяющие изолировать части приложения и имитировать поведение зависимостей.
Мок (mock) — это объект или функция, имитирующая поведение реального объекта в тестах. Моки используются для проверки взаимодействия между компонентами и контроля вызовов методов без выполнения их реальной логики.
Стаб (stub) — это упрощённая реализация функции или объекта, которая возвращает фиксированные данные и не выполняет реальных побочных эффектов. Стабы применяются для предсказуемого поведения зависимостей при тестировании.
Отличия:
| Параметр | Мок | Стаб |
|---|---|---|
| Основная цель | Проверка взаимодействий | Замена зависимости для теста |
| Возвращаемые данные | Можно настраивать и проверять | Обычно фиксированные данные |
| Слежение вызовов | Да | Нет (в базовом варианте) |
Slim.js ориентирован на компоненты с реактивным состоянием. Для тестирования таких компонентов моки позволяют:
Пример использования мок-сервиса для Slim-компонента:
import { Slim } from 'slim-js';
class UserServiceMock {
constructor() {
this.getUserCalls = 0;
}
getUser(id) {
this.getUserCalls++;
return Promise.resolve({ id, name: 'Mock User' });
}
}
class UserComponent extends Slim {
static get observedAttributes() { return ['user-id']; }
constructor() {
super();
this.user = null;
this.userService = new UserServiceMock();
}
connectedCallback() {
super.connectedCallback();
this.fetchUser();
}
fetchUser() {
this.userService.getUser(this.userId).then(user => {
this.user = user;
this.update();
});
}
get userId() {
return this.getAttribute('user-id');
}
render() {
return `<div>${this.user ? this.user.name : 'Loading...'}</div>`;
}
}
customElements.define('user-component', UserComponent);
В данном примере UserServiceMock отслеживает
количество вызовов метода getUser, что позволяет проверять,
как компонент взаимодействует с сервисом без обращения к реальному
API.
Стабы упрощают тестирование, возвращая заранее заданные данные, без необходимости отслеживать вызовы или состояние. Это полезно, когда важна только реакция компонента на входные данные.
Пример стаба:
class UserServiceStub {
getUser() {
return Promise.resolve({ id: 1, name: 'Stub User' });
}
}
class UserComponentWithStub extends UserComponent {
constructor() {
super();
this.userService = new UserServiceStub();
}
}
С помощью такого стаба компонент всегда получает предсказуемый объект пользователя, что упрощает тесты UI и рендеринга.
Slim.js хорошо сочетается с Jest, Mocha и другими инструментами для юнит-тестирования. Для моков и стабов в тестах применяются:
Пример интеграции с Jest:
import { UserComponent } from './UserComponent.js';
test('UserComponent вызывает getUser', async () => {
const mockService = { getUser: jest.fn().mockResolvedValue({ id: 1, name: 'Test User' }) };
const component = new UserComponent();
component.userService = mockService;
component.setAttribute('user-id', '1');
component.connectedCallback();
await new Promise(r => setTimeout(r, 0));
expect(mockService.getUser).toHaveBeenCalledWith('1');
expect(component.user.name).toBe('Test User');
});
Здесь мок позволяет проверить, что метод getUser был
вызван с правильным аргументом, а компонент корректно обновил
состояние.
Slim.js позволяет динамически подменять зависимости даже после создания компонента. Это полезно для сценариев, когда требуется эмулировать разные состояния сервиса:
component.userService = new class {
getUser() { return Promise.resolve({ id: 2, name: 'Dynamic Mock' }); }
}();
component.fetchUser();
Такой подход обеспечивает гибкость при написании комплексных интеграционных тестов, где один компонент взаимодействует с несколькими сервисами.
await или
Promise, чтобы правильно тестировать реактивное состояние
компонента.Моки и стабы являются фундаментом надёжного тестирования в Slim.js и позволяют создавать чистые, модульные и предсказуемые тесты для сложных веб-компонентов.