简体   繁体   中英

How to unit test rxjs debounceTime logic (Angular)?

With my lack of knowledge about RxJs I copy->paste used some code using it, modified it and now failing to test it...

Here is the whole component:

import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operator/map';
import { debounceTime } from 'rxjs/operator/debounceTime';
import { distinctUntilChanged } from 'rxjs/operator/distinctUntilChanged';
import { _catch } from 'rxjs/operator/catch';
import { _do } from 'rxjs/operator/do';
import { switchMap } from 'rxjs/operator/switchMap';
import { of } from 'rxjs/observable/of';

import { ApiService } from '../../services/api/api.service';

import { ISearchSuggestion } from './search.interface';

@Component({
  selector: 'msm-search',
  templateUrl: './search.component.html'
})
export class SearchComponent {
  public model: string;

  private _isSearching = false;
  get isSearching() { return this._isSearching; }

  constructor(
    private router: Router,
    private apiService: ApiService
  ) {}

  search = (text$: Observable<string>) => {
    return _do.call(
      switchMap.call(
        _do.call(
          distinctUntilChanged.call(
            debounceTime.call(text$, 300)),
            this.enableSearching.bind(this)
          ),
        this.performSearch.bind(this)
      ),
      () => {
        this._isSearching = false;
      }
    );
  }

  private enableSearching(term: string) {
    if (term.length > 2) {
      this._isSearching = true;
    }
  }

  private performSearch(term: string) {
    if (term.length > 2) {
      return _catch.call(
        _do.call(this.apiService.getSearchSuggestions(term)),
        () => of.call([])
      )
    }
  }
}

I want to test search but neither setTimeout neither jasmine.tick() seems to do a trick, here is example of what I came up with:

it('Should get suggestions if search term is longer than 2 characters', (done) => {
  const searchTerm = '123test';
  const stringObservable = new Observable<string>(observer => {
    setTimeout(() => {
      observer.next(searchTerm);
      observer.complete();
    }, 50);
  });
  spyOn(apiService, 'getSearchSuggestions');
  component.search(stringObservable);
  setTimeout(() => {
    expect(apiService.getSearchSuggestions).toHaveBeenCalledWith(searchTerm);
    done();
  }, 500);
});

What am I doing wrong?

tick should be the thing to use to achieve that

component.search(stringObservable);
tick(500);
expect(apiService.getSearchSuggestions).toHaveBeenCalledWith(searchTerm);

This doesn't work?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM