Жасмин шпион не переписывает ложную реализацию - PullRequest
0 голосов
/ 11 января 2019

В методе ngOnInit класса, который я тестирую, я вызываю функцию сервиса, который перезапускает наблюдаемое. Я реализовал макет для службы, но я пытаюсь использовать шпиона для этого точного теста. В моем понимании, шпион перезаписывает фиктивную реализацию, если я не вызову «.and.callThrough ()» для шпиона. Проблема состоит в том, что каждый раз, когда ложная реализация все еще выполняется, я настроил шпиона для этой функции.

Я попытался переместить шпиона в раздел beforeEach, который не помог. Также я попытался использовать шпион без расширения ".and.callFake ()". Но это не помогло.

файл spec.ts:

fdescribe('AppComponent', () => {
  let fixture;
  let component;
  let dataServiceMock: DataServiceMock;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [RouterTestingModule],
      declarations: [AppComponent],
      providers: [{ provide: DataService, useClass: DataServiceMock }],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();

    dataServiceMock = TestBed.get(DataService);
  });


  fit('should not show navigation if not logged in', async(() => {
   spyOn(dataServiceMock,'getCurrentUser').and.callFake(() => {
     console.log('IN CALL FAKE')
     throwError(new Error('induced error'))
   });
 }));

реализация сервисного макета:

export class DataServiceMock {
  currentUser: User;

  private createValidUser() {
    let validUser = new User();
    validUser.username = 'valid';
    validUser.password = 'valid';
    validUser.role = 'valid';
    this.currentUser = validUser;
  }

  public getCurrentUser(): Observable<User> {
    this.createValidUser();
    return of(this.currentUser);
  }

ngOnInit проверяемого компонента:

ngOnInit(): void {
  this.dataService.getCurrentUser().subscribe(user => {
    this.currentUser = user;
    console.log('received user:', this.currentUser)
  })
}

Я ожидаю, что в журнале консоли выводится «IN CALL FAKE» и выдается «вызванная ошибка», но вместо этого консоль выводит «полученный пользователь:» и validUser, созданный в макете службы.

1 Ответ

0 голосов
/ 12 января 2019

Это просто проблема времени. В вашем beforeEach() вы выполняете fixture.detectChanges(). Это выполняет ngOnInit(), подробности смотрите в документах . Таким образом, решение состоит в том, чтобы НЕ вызывать fixture.detectChanges() там, но переместить его в спецификацию ПОСЛЕ ТОГО, КАК вы изменили возврат с getCurrentUser.

Вот рабочий StackBlitz , показывающий, как работает этот тест. Я также изменил несколько деталей, чтобы получить рабочий тест:

  • Ваш callFake фактически ничего не возвращал. Выглядело так, как будто вы хотели вернуть throwError(), однако это вызвало дальнейшие проблемы, поскольку у вас фактически нет никакой наблюдаемой обработки ошибок в вашем компоненте, поэтому нет смысла проверять это.
  • Я добавил фальшивое возвращение return of({username: 'test'}) только для того, чтобы позволить .subscribe() в ngOnInit() вашего компонента настроить что-то, что можно было протестировать - тогда я установил простое ожидание, которое проверяло, что component.currentUser.username был установлен правильно.
  • Я удалил ненужную оболочку async(), которая была у вас в этой спецификации - поскольку вы используете для тестирования синхронные Observables (созданные с of()), в этом нет необходимости.

Вот новая спецификация от этого StackBlitz:

it('should not show navigation if not logged in', () => {
  spyOn(dataServiceMock,'getCurrentUser').and.callFake(() => {
    console.log('IN CALL FAKE')
    //  throwError(new Error('induced error'))
    return of({username: 'test'})
  });
  fixture.detectChanges();
  expect(component.currentUser.username).toEqual('test');
});

Надеюсь, это поможет.

...