Как протестировать функцию с подпиской, которая возвращает void - PullRequest
0 голосов
/ 02 октября 2018

У меня есть TypeScript ModelService с функцией edit:

edit(model: Model): Observable<Model> {
  const body = JSON.stringify(model);
  return this.http.put(`/models/edit/${model.id}`, body));
}

И у меня есть TypeScript EditComponent с функцией edit, который подписывается на сервис и выполняет навигацию при полученииответ:

edit(model: Model): void {
  this.service
    .edit(model)
    .subscribe(() => this.router.navigate([`/models/details/${model.id}`]);
}

Как лучше всего протестировать функцию edit этого компонента?

У меня есть тест Жасмин, который делает это:

// Setup
TestBed.configureTestingModule({
  declarations: [EditComponent],
  providers: [
    {
      provide: ModelService,
      useValue: jasmine.createSpyObj('ModelService', ['edit'])
    }
  ]
});
const fixture = TestBed.createComponent(EditComponent);
const component = fixture.componentInstance;
const modelService = fixture.debugElement.injector.get(ModelService);
fixture.detectChanges();

// Test
it('should call edit', () => {
  fakeAsync(() => {
    component.edit(model);
    expect(modelService.edit).toHaveBeenCalled();
  });
});

Но с этим тестом я всегда получаю SPEC HAS NO EXPECTATIONS при запуске.Мое понимание fakeAsync заключается в том, что он работает синхронно, поэтому я подумал, что это будет работать.

Я также пытался использовать многочисленные варианты async, tick() и done(), но они либо выдают то же сообщение, либо выдают ошибку Cannot read property 'subscribe' of undefined при вызове функции edit компонента.

В других тестах я смог использовать return fixture.whenStable().then(), и это прекрасно работает (какописано здесь ), но я не думаю, что это работает здесь, так как функция компонента возвращает void вместо Promise.

Какой лучший способ протестировать эту функцию компонента?

1 Ответ

0 голосов
/ 02 октября 2018

Для SPEC HAS NO EXPECTATIONS

Не похоже, что это правильный способ использования fakeAsync, и поэтому он не сказал никаких ожиданий.Это должно быть:

it('should call edit', fakeAsync(() => {
  component.edit(model);
  expect(modelService.edit).toHaveBeenCalled();
});

В любом случае modelService.edit() на самом деле является вызовом, который можно ожидать синхронно, потому что он вызывается внутри component.edit().

Так что вы можете просто проверить егокак это:

it('should call edit', () => {
  component.edit(model);
  expect(modelService.edit).toHaveBeenCalled();
});

Для Cannot read property 'subscribe' of undefined

Поскольку вы создаете шпионский объект без каких-либо возвратов.Следовательно, modalService.edit() возвращает undefined и не может быть прочитано свойство 'подписка'.В этом случае я обычно заглушаю его результат, создавая новый Observable или используя of () и возвращая значения, с которыми этот компонент может взаимодействовать.

jasmine.createSpyObj('ModelService', { edit: of() })
...