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

标签 angular rxjs angular-test

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

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

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

html

我通过 async 管道在 HTML 中订阅我的 observable。

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

我错过了用 of() 运算符将 ['Munich', 'Münster'] 作为 Observable 返回。我应该使用 tick(750) 来等待事件更改的特定去抖时间。

关于Angular 7 测试 - 模拟具有去抖时间的输入事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55796982/

相关文章:

javascript - Angular 中动态注入(inject)组件

excel - 如何在 Angular 中将 Excel 模板的设计作为对象导入

Angular http请求可观察到的错误没有捕获错误?

angular - 没有项目支持 Angular 中的 'test' 目标

angular - 在 Angular 4 项目的功能性 e2e Protractor 测试中模拟休息调用

javascript - 如何在 javascript/Angular4+ 中用垂直线显示分层垂直数据?

javascript - Office.js Excel : detect if user adds/removes columns (or rows)

javascript - 继续跟踪 RxJs 中的 "original"项目

Angular 4 Ngx-datatable Filter not working object is null but accessed (even with if condition)

angular - 设置 Angular 8 测试的顺序