Tommazo
Tommazo

Reputation: 87

Unit Test nested service with subscription

I'm trying to unit test a service that has a method that returns void but in which it calls another service and subscribes to it. The problem is I keep getting the error: this.secondService.getPage is not a function. What am i doing wrong?

this is how the service I'm testing looks like:

public jumpTo(arg1: any, arg2: any): void {

     this.secondService.getPage(arg01: any, arg02: any).subscribe(response => {
       // do stuff
     })

  }

while my spec file looks like this:

describe('NavigationService', () => {
    let navigation: NavigationService
    let secondServiceSpy: any

    beforeEach(() => {

        secondServiceSpy = jasmine.createSpyObj('SecondService', ['getPage'])
        TestBed.configureTestingModule({
            providers: [
                NavigationService,
                { provide: SecondService, useValue: secondServiceSpy }
            ]
        })
        navigation = TestBed.get(NavigationService)
    })

    it('should jump to another step', () => {
        navigation.jumpTo('value1', 'value2' )
        expect(secondServiceSpy.getPage).toHaveBeenCalled()
    })
})

Upvotes: 0

Views: 1549

Answers (2)

uminder
uminder

Reputation: 26170

You should execute your unit test in the in the fakeAsync zone.

import { fakeAsync, flush } from '@angular/core/testing';
...
it('should jump to another step', fakeAsync(() => {
    navigation.jumpTo('value1', 'value2' );
    flush(); 
    expect(secondServiceSpy.getPage).toHaveBeenCalled();
}));

Please consult https://angular.io/api/core/testing/fakeAsync and https://angular.io/api/core/testing/flush for furthe information.

Upvotes: 0

AliF50
AliF50

Reputation: 18869

import { of } from 'rxjs/observable/of';
....
describe('NavigationService', () => {
    let navigation: NavigationService
    let secondServiceSpy: any
    let secondService: SecondService; // add this variable

    beforeEach(() => {

        secondServiceSpy = jasmine.createSpyObj('SecondService', ['getPage'])
        TestBed.configureTestingModule({
            providers: [
                NavigationService,
                { provide: SecondService, useValue: secondServiceSpy }
            ]
        })
        navigation = TestBed.get(NavigationService)
        secondService = TestBed.get(SecondService); // populate the value
    })

    it('should jump to another step', () => {
        // make the function return an observable.
        secondServiceSpy.getPage.and.returnValue(of(...)); // whatever you to return for the subscribe
        navigation.jumpTo('value1', 'value2' )
        expect(secondServiceSpy.getPage).toHaveBeenCalled();
        // I don't know if the expect of above is a good assertion or will work
        // You should do assertions of what happens in the subscribe block.
    });

Upvotes: 1

Related Questions