5

i'm trying do a test to know if a function of a service is called, but always it returns me that is not calling. I do not know what I'm doing wrong. The function that i want know if it's called this inside a switchMap, this function is a service. (this.heroSearchService.search(term))

This is the message that shows Expected spy search to have been called.

This is my component.

export class HeroSearchComponent implements OnInit {
  heroes: Observable<Hero[]>;
  private searchTerms = new Subject<string>();

  constructor(
    private heroSearchService: HeroSearchService
  ) {}

  search(term: string): void {
    // Push a search term into the observable stream.
    this.searchTerms.next(term);
  }

  ngOnInit(): void {    
    this.heroes = this.searchTerms.pipe(
      debounceTime(300), // wait for 300ms pause in events
      distinctUntilChanged(), // ignore if next search term is same as previous
      switchMap(term => term ? this.heroSearchService.search(term) : of<Hero[]>([])),
      catchError(error => {
        // TODO: real error handling
        console.log(`Error in component ... ${error}`);
        return of<Hero[]>([]);
      })
    );    
  }
}

This is my mock service.

export const MockHeroSearchService = {
    search: (term: string): Observable<Array<Hero>> => {
        let heroes = defaultHeroes.filter(hero => hero.name.includes(term)) as Array<Hero>;
        return of(heroes);
    }
}

This is my test file. Inside this file this the test where i created the spy (spyOn(heroSearchService, 'search').and.callThrough();) and the expect that fails is expect(heroSearchService.search).toHaveBeenCalled();

beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [CommonModule, HttpClientTestingModule, RouterTestingModule, FormsModule], //If our component uses routing, httpclient
            declarations: [HeroSearchComponent], //Here we put all the components that use our component. 
            providers: [
                //Here we can inject the dependencies that our component needs.
                //If our dependecies are services, we can create a simulated service.
                { provide: HeroSearchService, useValue: MockHeroSearchService },
            ]
        }).compileComponents();
    }));

    //Arrange
    beforeEach(() => {
        heroSearchService = TestBed.get(HeroSearchService);
        fixture = TestBed.createComponent(HeroSearchComponent);
        debugElement = fixture.debugElement;
        heroSearchComponent = fixture.componentInstance;
        //fixture.detectChanges();// Comments, so that it does run the of method ngOnInit();
    });

   fit('should with the correct search term, the variable heros have at least a hero', fakeAsync(() => {
        spyOn(heroSearchService, 'search').and.callThrough();
        fixture.detectChanges();

        const input = fixture.debugElement.query(By.css('#search-box'));
        input.nativeElement.value = 'And';
        input.triggerEventHandler('keyup', null);

        tick(600);
        fixture.detectChanges();

        expect(heroSearchService.search).toHaveBeenCalled();                       
    }));

I too run the code coverage and this is result. Where is shows that line is execute.

enter image description here

I hope you can help me. excuse me for my english.

  • Where do you execute the `search()` method in your test? Is it linked to `keyup` event in the template? If so, are you sure that `search` is executed in your test? This may give you some inspiration https://stackoverflow.com/questions/51463410/angular-jasmine-test-not-able-to-trigger-observable-created-with-fromevent-rxjs – Picci Sep 20 '18 at 06:03
  • @Picci, thanks for answer. Yes the keyup event execute the "search" method of the component and this execute "next", this should execute the "search" method of the service, but this never execute. I Will review the link. Thanks you. – Andres Echeverry Sep 20 '18 at 17:00
  • @Picci Check the link, but this is not my case. – Andres Echeverry Sep 20 '18 at 17:04

1 Answers1

1

reviving this rather old threat as I have come across the same / similar issue. Have you beeen able to find a solution for it yet? In my case - thanks to logging intermediate values - I could verify that the ids$ Observable is firing.

this.testObs$ = this.ids$.pipe(
      switchMap(ids => {
        const promises = ids.map(id => {
          return this.testApi.getPayer(id).toPromise();
        });
        return Promise.all(promises);
      })
    );
basti
  • 123
  • 1
  • 10