Как сделать мокацию сервиса внутри Component Test Cypress для независимого компонента Angular

Вопрос или проблема

Как предоставить мок для самостоятельного компонента в тесте компонентов Cypress?

У меня есть эта функция монтирования внутри моего теста:

function mount() {
  cy.mount(TestComponent, {
    providers: [
      provideHttpClient(),
      provideHttpClientTesting(),
      { provide: TestService, useValue: mockTestService },
    ],
  });
}

Компонент TestComponent выглядит так:

@Component({
  selector: 'app-test',
  standalone: true,
  imports: [TestModule],
  templateUrl: './test.component.html',
  styleUrl: './test.component.scss',
})
export class TestComponent { /* какой-то код */ }

Модуль TestModule предоставляет TestService и некоторые другие сервисы, от которых он зависит (которые не нужны для моего теста, так как я хочу использовать мок).

Проблема в том, что это не работает. Тест все еще вызывает оригинальный сервис вместо мока.

Поскольку вы используете useValue, замокированные содержимое внутри сервиса не распознается, и я получаю следующую ошибку.

(необработанное исключение) TypeError: this.testService.getData не является функцией


Решение:

Вы должны использовать useClass при мокировании сервиса.

cy.mount(AppComponent, {
  providers: [
    // provideHttpClient(),
    provideHttpClientTesting(),
    { provide: TestService, useClass: MockTestService },
  ],
});

Полный код:

import { of } from 'rxjs';
import { AppComponent, TestService } from './app.component'
import { provideHttpClientTesting } from '@angular/common/http/testing';

export class MockTestService {
  getData() {
    return of([
      { testy: 1 }
    ])
  }
}

describe('AppComponent', () => {
  it('монтируется', () => {
    cy.mount(AppComponent, {
      providers: [
        // provideHttpClient(),
        provideHttpClientTesting(),
        { provide: TestService, useClass: MockTestService },
      ],
    });
  })
})

Ответ или решение

Как реализовать мокирование сервиса в Cypress для тестирования Angular Standalone компонента

В рамках разработки приложений на Angular одной из критически важных задач является тестирование компонентов. С помощью Cypress можно эффективно проводить тесты компонент, включая и возможность мокирования сервисов. Однако, когда дело доходит до тестирования Standalone компонентов, могут возникнуть некоторые сложности. В этой статье мы подробно разберём, как корректно создать мок для сервиса в Cypress.

Проблема

У вас есть компонент, который требует внедрения сервиса для работы, и вы хотите протестировать его, не обращаясь к реальному сервису. Ваша текущая реализация, которая использует useValue, не работает должным образом, поскольку в этом случае методы мок-сервиса не распознаются, что приводит к ошибкам выполнения, таким как:

TypeError: this.testService.getData is not a function

Решение

Чтобы обойти указанную проблему и корректно протестировать компонент с использованием Cypress, необходимо использовать useClass вместо useValue при предоставлении мок-сервиса. Ниже приведён пошаговый процесс:

Шаг 1: Создание мок-сервиса

Для начала вам потребуется создать класс мок-сервиса, который будет имитировать методы реального сервиса. Например, можно создать класс MockTestService следующим образом:

import { of } from 'rxjs';

export class MockTestService {
  getData() {
    return of([{ testy: 1 }]);
  }
}

Этот мок-сервис будет возвращать фиктивные данные, когда вызывается метод getData().

Шаг 2: Настройка функции mount

Теперь необходимо обновить функцию mount в вашем тесте, чтобы использовать созданный мок-сервис. Вот как это должно выглядеть:

import { provideHttpClientTesting } from '@angular/common/http/testing';
import { TestComponent, TestService } from './test.component'; // Убедитесь, что пути корректны

function mount() {
  cy.mount(TestComponent, {
    providers: [
      provideHttpClientTesting(),
      { provide: TestService, useClass: MockTestService },
    ],
  });
}

Этот код корректно инжектирует ваш мок-сервис вместо реального, благодаря чему весь функционал тестируемого компонента будет работать с вашими заранее заданными данными.

Шаг 3: Написание теста

Теперь, после настройки компонента и мок-сервиса, вы готовы написать тест:

describe('TestComponent', () => {
  it('должен корректно монтироваться и использовать мок-сервис', () => {
    mount();
    // Ваши проверки здесь, например:
    cy.get('.some-element')
      .should('contain', 'ожидаемое значение');
  });
});

Выводы

Работа с моками в Cypress для тестирования Angular Standalone компонентов может показаться сложной, но, следуя указанным шагам и использованию useClass для внедрения мок-сервисов, можно успешно обойти возникшие трудности. Это позволит вам проводить тесты над компонентами без зависимости от их реальных сервисов, что значительно упростит процесс разработки и повысит стабильность тестов.

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

Оцените материал
Добавить комментарий

Капча загружается...