celsomtrindade
celsomtrindade

Reputation: 4671

Angular 4 unit test service calling http service

I have a service that is calling a http function:

processLogin(info) {
    return this._call.post('login', info).subscribe(response => {
        if (response.status === 'success') {
            this._auth.login(response.object);
            return true;
        }

        return false;
    }, error => {
        return false;
    });
}

And this is the test I'm trying to make:

describe('Facebook Login', () => {
    let service: FacebookLoginService;
    let call: CallService;

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                FacebookLoginService,
                { provide: CallService, useClass: CallServiceMock },
            ]
        });

        service = TestBed.get(FacebookLoginService);
        call = TestBed.get(CallService);
    });

    it('should process the login when the post method return success', () => {
        spyOn(call, 'post').and.returnValue(Observable.of({status: 'success'}));

        service.processLogin('any').subscribe(response => {
            console.log(response);
        });
    });
});

However, when I run the test I keep getting the error message

processLogin().subscribe( ... ) is not a function

And if I change the type of response mocked to anything but Observable.of, I get the error message

call.post.subscribe( ... ) is not a function

Why is it not wokirng? I have a very similar test on another service that also calls call.post() and it's working.

Upvotes: 1

Views: 696

Answers (1)

Estus Flask
Estus Flask

Reputation: 223064

processLogin returns not an observable but a subscription, so there will be no subscribe method on it. Returned values in subscribe callbacks are ignored, so processLogin won't work as expected.

It likely should be changed to return an observable instead:

return this._call.post('login', info).map(response => { ... });

Then it can be tested like:

spyOn(_call, 'post').and.returnValue(Observable.of({ status: 'success' }));

const login$ = service.processLogin('any');
expect(_call).toHaveBeenCalledWith('login', 'any');

login$.subscribe(response => {
  expect(response).toBe(...);
}, err => { throw err });

It will also need to mock _auth.

Upvotes: 1

Related Questions