角度 7 测试 - 模拟具有去抖动时间的输入事件



在开始这个问题之前。我知道,有很多类似的问题喜欢我。但是没有任何解决方案能够帮助我。

我使用 rxjs 创建了一个自定义自动完成,并想测试是否在输入事件上调用了方法。但是错误说该方法从未被调用,例如:

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

.html

我通过async管道订阅了我在 HTML 中的可观察对象。

      <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');
        });
      }));

我也尝试将fakeAsynctick(750)一起使用。但没有任何帮助。测试中的console.log还显示一个空字符串作为输入值。所以也许我模拟了一个错误的事件。

我的测试使用以下配置:

  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)来等待事件更改的特定去抖动时间。

您应该调用.subscribe()进行Observable。并且你应该在 switchMap 中返回一个Observable,所以,你不能返回一个带有间谍的数组,但是 可观察: const spy = (cityServiceStub.getLocation as jasmine.Spy).and.returnValue(of(['Munich', 'Münster'])); <</p>

div class="one_answers">

此代码是否在测试之外工作?您尚未发布整个组件,但是在您发布的片段中,我看不到任何地方都在进行订阅。在至少有一个订阅之前,可观察对象不会开始发出(请参阅此处(。

我在我的副项目中实现了您的测试,只有在订阅 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()

最新更新