mat-table not populated with data in test

Viewed 2668

As the title suggests, i am trying to test a method that fetches data from an api and then populates the mat-table with the data from the returned observable. However the mat-table is not populated; logging in the console the table html displays the table's html, but with the "tbody" tag empty, hence unpopulated.

The test error reads: " Type ' to contain 'Vanilla Sky'"

Component.Spec

it('should display the film info in table', fakeAsync(() => {
    const searchResults = new Array<ISearchItem>();
    let filmMock = <ISearchItem>{
        imdbID: 'tt0259711',
        Title: 'Vanilla Sky',
        Year: '2001',
        Type: 'movie',
        Poster: 'https://m.media-amazon.com/images/M/MV5BYzFlMTJjYzUtMWFjYy00NjkyLTg1Y2EtYmZkMjdlOGQ1ZGYwL2ltYWdlXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_SX300.jpg'
    };

    searchResults.push(filmMock);

    let searchResponse = <ISearchResponse>{
        Search: searchResults,
        totalResults: '1',
        Response: 'True'
    };

    component.currentPaginationData = {
        length: 1,
        pageIndex: 1,
        pageSize: 10,
        previousPageIndex: 0
    }

    const imdbServiceStub: ImdbService = fixture.debugElement.injector.get(ImdbService);
    let searchResponseObs = of(searchResponse);
    spyOn(imdbServiceStub, 'searchImdbFilmDatabase').and.returnValue(of(searchResponseObs));

    component.searchDatabaseByKeyword('sky', true);

    fixture.detectChanges();
    tick();
    fixture.detectChanges();

    table = fixture.debugElement.query(By.css('#filmList')).nativeElement;

    console.log(table);

    expect(imdbServiceStub.searchImdbFilmDatabase).toHaveBeenCalled();
    expect(table.innerText).toContain(filmMock.Title);
}));

Component:

 searchDatabaseByKeyword(searchTerm: string, init?: boolean) {
        let displayData: boolean = false;
        let searchDbSub = this.imdbService.searchImdbFilmDatabase(searchTerm, this.currentPaginationData)
            .pipe(
                tap((data: ISearchResponse) => {
                    displayData = !(data.Response === 'False');
                    this.numberOfResults = parseInt(data.totalResults);

                    if (init) {
                        this.currentPaginationData = {
                            length: this.numberOfResults,
                            pageIndex: 1,
                            pageSize: 10,
                            previousPageIndex: 0
                        }
                    }
                }),
                map((data: ISearchResponse) => {
                    return data.Search
                })
            )
            .subscribe((value: Array<ISearchItem>) => {
                if (value && displayData) {
                    this.currentKeyword = searchTerm;
                    this.searchResults = value;

                    this.dataSource = new MatTableDataSource(this.searchResults);
                    this.dataSource.sort = this.sort;
                    this.paginator.length = this.numberOfResults;

                    if (init) {
                        this.dataSource.paginator = this.paginator;
                        this.paginator.pageIndex = this.currentPaginationData.pageIndex;
                        this.paginator.pageSize = this.currentPaginationData.pageSize;
                    }
                }
            }, (error: Error) => {
                throw error;
            });

        this.subs.push(searchDbSub);
    }

Service:

searchImdbFilmDatabase(searchTerm: string, paginationData?: IPaginatorData): Rx.Observable<any> {

    let baseUrl = this.searchFilmDatabaseEp + "&s=" + searchTerm;
    baseUrl += (paginationData) ? '&page=' + paginationData.pageIndex : '';
    baseUrl += '&r=json&type=movie';

    return this.http.get(baseUrl).pipe(
        tap((data: ISearchResponse) => {

            let tmp = this.store.select('searchReducer', 'searchData');
            console.log(tmp);

        }, (error: Error) => {
            throw error;
        })

    );
}
1 Answers

Whenever you have http calls (you are subscribing to a method) which are async in nature, your table might not be populated. Try using something like:

component.searchDatabaseByKeyword('sky', true);
fixture.whenStable().then(() => {
  fixture.detectChanges();
  expect(imdbServiceStub.searchImdbFilmDatabase).toHaveBeenCalled();
});
Related