Тестирование Angular 7 - симуляция входного события с временем отката - PullRequest
4 голосов
/ 22 апреля 2019

Прежде чем начать этот вопрос.Мне известно, что есть много похожих заданных вопросов, которые понравились моим.Но ни одно решение не помогло мне.

Я создал собственное автозаполнение с помощью rxjs и хочу проверить, вызывается ли метод для входного события.Но ошибка говорит о том, что метод так и не был вызван, например:

 Expected spy CityService.getLocation to have been called with [ 'mun' ] but it was never called.

html

Я подписываюсь на свой наблюдаемый в HTML через канал async.

      <input type="text" [(ngModel)]="location" class="form-control" id="locationSearchInput"/>
      <div class="spacer">
        <p class="invalid-feedBack" *ngIf="searchFailed && location.length > 0">Nothing found.</p>
        <ul id="search" *ngFor="let item of (search | async)">
          <li class="resultItem" type="radio" (click)="location = item">{{item}}</li>
      </ul>
    </div>

компонент

      ngOnInit(): void {
        this.search = fromEvent(document.getElementById('locationSearchInput'), 'input').pipe(
          debounceTime(750),
          distinctUntilChanged(),
          map((eventObj: Event) => (<HTMLInputElement>eventObj.target).value),
          switchMap((term: string) => this.cityService.getLocation(term)) <== should get called
        );
      }

тест

      const cityServiceStub: CityService = jasmine.createSpyObj('CityService', ['getLocation']);
      ...
      it('should search for location on init', async(() => {
        const spy = (<jasmine.Spy>cityServiceStub.getLocation).and.returnValue(['Munich', 'Münster']);

        fixture.detectChanges();

        const rendered: DebugElement = fixture.debugElement.query(By.css('#locationSearchInput'));

        rendered.nativeElement.value = 'mun';
        rendered.nativeElement.dispatchEvent(new Event('input'));

        fixture.detectChanges();

        fixture.whenStable().then(() => {
          console.log(rendered.nativeElement.value);
          expect(spy).toHaveBeenCalledWith('mun');
        });
      }));

Я также пытался использовать fakeAsync с tick(750).Но ничего не помогло.console.log в тесте также показывает пустую строку в качестве входного значения.Так что, возможно, я симулирую неправильное Событие.

Ответы [ 3 ]

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

Вы должны позвонить .subscribe() для Observable.И вы должны вернуть Observable внутри switchMap, поэтому вы не можете вернуть массив со шпионом, но наблюдаемый: const spy = (cityServiceStub.getLocation as jasmine.Spy).and.returnValue(of(['Munich', 'Münster']));

0 голосов
/ 02 мая 2019

Мой тест работал со следующей конфигурацией:

  it('should search for location on init', fakeAsync(() => {
    const spy = (<jasmine.Spy>cityServiceStub.getLocation).and.returnValue(of(['Munich', 'Münster']));

    fixture.detectChanges();

    const rendered: DebugElement = fixture.debugElement.query(By.css('#locationSearchInput'));

    rendered.nativeElement.value = 'mun';
    rendered.nativeElement.dispatchEvent(new Event('input'));

    tick(750);
    fixture.detectChanges();

    expect(spy).toHaveBeenCalledWith('mun');
  }));

Я пропустил просто вернуть ['Munich', 'Münster'] в качестве наблюдаемого с оператором of().И я должен был использовать tick(750), чтобы дождаться определенного времени отладки для изменения события.

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

Работает ли этот код вне теста? Вы не опубликовали весь компонент, но в отрывках, которые вы опубликовали, я не вижу нигде подписки. Observable не начнет излучать, пока у него не будет хотя бы одной подписки (см. здесь ).

Я реализовал ваш тест в своем стороннем проекте, и он начал работать только после подписки на Observable, вот так:

fromEvent(document.getElementById('locationSearchInput'), 'input').pipe(
  debounceTime(750),
  distinctUntilChanged(),
  map((eventObj: Event) => (<HTMLInputElement>eventObj.target).value),
  switchMap((term: string) => this.cityService.getLocation(term))
).subscribe()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...