Angular Testing - как протестировать Data Service с расширенным базовым классом - PullRequest
0 голосов
/ 02 апреля 2019

У меня проблемы с настройкой Тесты моих служб данных, я пытаюсь использовать HttpClientTestingModule, как определено в этих статьях Тестирование с помощью Angular HttpClient API , из этого ТАК вопрос , а также попытался inject из этой статьи Тестирование HttpClient , но я не могу заставить его работать.

Я считаю, что мои проблемы связаны с тем, что у меня есть глобальный DataService, который использует 3 поставщика услуг (HttpClient, NGXLogger и TranslateService из ngx-translate). Тогда у меня есть несколько служб данных, которые расширяют глобальный DataService, как, например,

@Injectable()
export class UserDataService extends DataService {
  constructor(protected http: HttpClient, protected logger: NGXLogger, protected translate: TranslateService) {
  super(http, logger, translate);
  this.url = `api/users`;
}

getUsers(): Observable<Users[]> {
  return super.getAll<User[]>(this.url);
}

Итак, как вы можете видеть, каждая расширенная служба данных (например, UserDataServices) заботится о введении трех необходимых зависимостей в вызов super.

Я пытаюсь кодировать свой тест, который выполняется с помощью Jest, с помощью следующего кода

describe('User Data Service', () => {
  let dataService: TemplateDataService;
  let httpTestingController: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        TranslateModule.forRoot(),
        LoggerModule.forRoot({ level: NgxLoggerLevel.ERROR, serverLoggingUrl: 'api/logging', serverLogLevel: NgxLoggerLevel.ERROR }),
      ],
      providers: [
        UserDataService
      ]
    });
    dataService = TestBed.get(UserDataService);
    httpTestingController = TestBed.get(HttpTestingController);
  });

it('should return an Observable<User[]>', () => {
  const dummyUsers = [
    { login: 'John' },
    { login: 'Doe' }
  ];

  dataService.getAll().subscribe((users: User[]) => {
    expect(users.length).toBe(2);
    expect(users).toEqual(dummyUsers);
  });

  const req = httpTestingController.expectOne(`api/users`);
  expect(req.request.method).toBe('GET');
  req.flush(dummyUsers);
});

и продолжает выдавать следующую ошибку

Unexpected value 'HttpClientModule' imported by the module 'HttpClientTestingModule'. Please add a @NgModule annotation.

Я тоже пытался с этим фрагментом кода, но я получаю ту же ошибку

it(
  'should get users',
  inject(
    [HttpTestingController, NGXLogger, TranslateService, DataService],
    (
      httpMocker: HttpTestingController,
      logger: NGXLogger,
      translate: TranslateService,
      dataServicer: DataService
    ) => {
      // ...our test logic here
    }
  )
);

Я довольно новичок в модульном тестировании (я начал на прошлой неделе), и я полностью заблокирован тестированием любой из моих Сервисов данных (с другой стороны, я в порядке с тестированием компонента с имитацией сервиса данных, но я хотел бы также проверить эти службы данных).

С технологической точки зрения в проекте используются Angular: ^7.2.10 и jest: ^23.6.0.

EDIT

Я забыл упомянуть, что DataService также является Службой, и я также попытался добавить его к providers в beforeEach(), и я все еще получаю ту же ошибку (Unexpected value 'HttpClientModule'...). Как показано ниже

beforeEach(() => {
  TestBed.configureTestingModule({
    imports: [
      HttpClientTestingModule,
      TranslateModule.forRoot(),
      LoggerModule.forRoot({ level: NgxLoggerLevel.ERROR, serverLoggingUrl: 'api/logging', serverLogLevel: NgxLoggerLevel.ERROR }),
    ],
    providers: [
      DataService,
      UserDataService
    ]
  });
});

Также, чтобы дать немного больше обзора DataService, вот его сокращенная версия.

export class DataService {
  constructor(protected http: HttpClient, protected logger: NGXLogger, protected translate: TranslateService) {}

  get<T>(id?: string, options?: HttpOptions): Observable<T> {
    const caller = findCaller(new Error());
    const uriWithId = id ? `/${id}` : '';
    const requestUrl = this.addGlobalQueryParams(`${this.url}${uriWithId}`);
    this.logger.debug(`DataService - GET method [${caller}] - START - URL:: ${requestUrl}`);

    return this.http.get<T>(requestUrl, options).pipe(map((response: any) => {
      this.logger.debug(`DataService - GET method [${caller}] - END - URL:: ${requestUrl} - Response:: `, response);
      return response;
    }));
  }

  getAll<T>(url?: string, options?: HttpOptions): Observable<T> {
    const caller = findCaller(new Error());
    if (url) {
      this.logger.debug(`DataService - POST method [${caller}] - START - URL:: `, url);
      return this.http.post<T>(url).pipe(map((response: any) => {
        this.logger.debug(`DataService - POST method [${caller}] - END - URL:: ${url} - Response:: `, response);
        return response;
      }));
    }
  }
}

РЕДАКТИРОВАТЬ 2

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

...