【问题标题】:Angular2 unit testing a switchMapAngular2单元测试switchMap
【发布时间】:2016-05-24 12:10:17
【问题描述】:

简单的问题:

我已经按照教程:here 我有以下代码:

this.term.valueChanges
  .debounceTime(400)
  .distinctUntilChanged()
  .switchMap(term => this.wikipediaService.search(term));

其中 term 是从 AbstractControl 继承的 Control,如何触发 valueChanges 可观察属性,以便执行单元测试?

【问题讨论】:

  • 我现在正在努力解决这个确切的问题。如果我删除 debounceTime() 调用,我可以让事情正常工作,但是我总是从 zone.js 收到一个错误,说我有一个定期计时器仍在队列中。

标签: unit-testing angular karma-jasmine


【解决方案1】:

我想我遇到了同样的问题。 我试图测试 heroService.searchHeroes 被调用:

  ngOnInit() {
    this.heroes$ = this.searchTerms
      .pipe(
        debounceTime(300),
        distinctUntilChanged(),
        switchMap((term: string) => this.heroService.searchHeroes(term))
      );
  }

我只需要调用一次tick(500) 就可以修复它

  it('should call HeroService.searchHeroes', fakeAsync(() => {
    spyOn(heroService, 'searchHeroes').and.returnValue(component.heroes$);
    let searchField: DebugElement = fixture.debugElement.query(By.css('#search-box'));
    searchField.nativeElement.value = 'i';
    searchField.nativeElement.dispatchEvent(new Event('keyup'));
    tick(500);
    expect(heroService.searchHeroes).toHaveBeenCalled();
  }));

【讨论】:

    【解决方案2】:

    我在以下问题中找到了解决方法:

    https://github.com/angular/angular/issues/8251

    本质上存在错误行为,但您可以使用如下代码进行基本测试:

    it("filter input changed should update filter string",
    
        fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
            let fixture = tcb.createFakeAsync(MyComponent);
            let component = fixture.componentInstance as MyComponent;
    
            fixture.detectChanges();
    
            // Trigger a new value to emit on the valueChanges observable
            //
            component.filter.updateValue("testing");
    
            // There's buggy behavior with multiple async events so we 
            //  need to run tick() twice to get our desired behavior
            //  https://github.com/angular/angular/issues/8251
            //
            tick();
            tick(500);
    
            // Now we can inspect the results of the subscription in the 
            //  original component
            //
            expect(component.filterString).toBe("testing");
        })));
    

    ...这是一个看起来像这样的组件:

    export class MyComponent {
    
        filter = new Control();
    
        /** The current filter string */
        filterString: string;
    
        constructor() {
            // Subscribe to changes in the filter string
            //
            this.filter.valueChanges
                .debounceTime(200)
                .distinctUntilChanged()
                .subscribe((filterString: string) => {
                    this.filterString = filterString;
                });
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-01-16
      • 1970-01-01
      • 2018-09-29
      • 1970-01-01
      • 2016-10-19
      • 2016-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多