Как смоделировать внедренный сервис в функции с Инжектором - PullRequest
0 голосов
/ 31 марта 2019

В Angular 7.x у меня есть глобальная обработка ошибок, которая внедряет его услуги с помощью Injector. Таким образом, каждая функция имеет ссылку на инжектор, например:

import { ErrorHandler, Injectable, Injector, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { LoggingService } from '../logging/logging.service';
import { EnvironmentService } from '../services/environment.service';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {
  constructor(private readonly injector: Injector, private readonly zone: NgZone) {}

  handleError(error: any): void {
    // Handle Client Error (Angular Error, ReferenceError...)
    this.processError(error);

    throw error;
  }

  processError(error: any): void {
    const environmentService = this.injector.get(EnvironmentService);
    const environment = environmentService.getEnvironment();
    if (!environment.production) {
      console.error(error);
    } else {
      // Log the expection to the logger
      this.logException(error);

      this.zone.run(() => {
        this.navigateToErrorPage(error);
      });
    }
  }

  private logException(error: any): void {
    const loggingService = this.injector.get(LoggingService);
    loggingService.logException(error);
  }

  private navigateToErrorPage(error: any): void {
    const router = this.injector.get(Router);
    router.navigate(['/500'], { queryParams: { error } });
  }
}

Как видите, в функции processError я внедряю службу среды. Единственная цель этого сервиса - смоделировать окружение в моих тестах спецификаций. Я делаю это в другом сервисном тесте, но использую его для внедрения зависимостей, а не для функции this.injector.get(...).

Кто-нибудь знает, как я это высмеиваю?

it('should log the error if the environment is in production', () => {
  // Arrange
  const environmentSpy = jasmine.createSpyObj('EnvironmentService', 'getEnvironment'); ??? How do I mock this ???

  const error: Error = new Error('New Error');
  spyOn<any>(errorHandler, 'logException');
  // Act
  errorHandler.processError(error);

  // Assert
  expect(errorHandler['logException']).toHaveBeenCalledWith(error);
});

1 Ответ

0 голосов
/ 01 апреля 2019

Вы можете шпионить за Инжектором и возвращать поддельный класс вместо EnvironmentService, который имеет настроенный метод getEnvironment():

spyOn(TestBed.get(Injector), 'get').and.callFake((token) => {
    if (token === EnvironmentService) {
        // Return a mocked EnvironmentService class
        return {
            getEnvironment: () => { return { production: true }; }
        };
    } else {
        // Otherwise, return whatever was originally defined in the TestBed
        return TestBed.get(token);
    }
});

В качестве альтернативы, вы можете использовать настоящий Инжектор и шпионить за EnvironmentService.вместо:

spyOn(TestBed.get(EnvironmentService), 'getEnvironment').and
    .returnValue({ production: true });
...