Angular2单元测试switchMap

时间:2016-05-24 12:10:17

标签: unit-testing angular karma-jasmine

简单问题:

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

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

如果术语是从Control继承的AbstractControl,我如何触发valueChanges observable属性,以便我可以执行单元测试?

2 个答案:

答案 0 :(得分:0)

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

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

    }
}

答案 1 :(得分:0)

我想我遇到了同样的问题。 我试图测试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();
  }));