Unit testing function ehich return observable of observables

153 Views Asked by At

I've got a problem with unit testing function like this:

loadData({prop1, prop2, prop3}: Props): Observable<unknown> {
    return this.dataService.clearData().pipe(
         concanMap(() => this.personalDataService.getData(prop1)),
         concanMap(() => this.extendedDataService.getData(prop2)),
         concanMap(() => this.weatherDataService.getData(prop3))
    );
}

I want to do this based on spyOn's. Something like this:

it('should correctly load data', () => {
    spyOn(dataService, 'clearData');
    spyOn(personalDataService, 'getData');
    spyOn(extendedDataService, 'getData');
    spyOn(weatherDataService, 'getData');

    spectator.service.loadData({
          prop1: '',
          prop2: '',
          prop3: ''
    })

    expect(dataService.clearData).toHaveBeenCalled();
    expect(personalDataService.getData).toHaveBeenCalled();
    expect(extendedDataService.getData).toHaveBeenCalled();
    expect(weatherDataService.getData).toHaveBeenCalled();
});

I've got an error:

TypeError: Cannot read properties of undefined (reading 'pipe')

It's quite obvious because dataService.clearData is a mock, so I need to return some value from this method:

spyOn(dataService, 'clearData').and.returnValue(of());

This solution is bad because the other services calls can't be triggerred.

Do you have any idea how to test this function?

1

There are 1 best solutions below

0
dopoto On

I think your test should rather check that loadData returns as expected, something like this:

// mock clearData() and the three getData() here

testedComponent.loadData(...).subscribe((actual) => {
    // assert that actual is as expected
})

In your test, you just call spectator.service.loadData(), which leaves you with a cold observable.