angular2 testing using jasmine for subscribe method

58,097

Solution 1

You need to return something with a subscribe method, as the component calls subscribe directly from login. A string does not. You could just return an object with a subscribe function and it should work

and.returnValue({ subscribe: () => {} });

Or if you want to pass a real observable, you could

and.returnValue(Observable.of('some value'));

You might need to import rxjs/add/observable/of

Solution 2

On rxjs v6 you should use of instead of Observable.of or Observable.from e.g

const loginService: any = {
    getUser: () => of(['Adam West']),
};

and import

import { of } from 'rxjs';

Solution 3

Change your spy for the 'login' method on your authService to return an observable instead of a value. You'll need to import:

import 'rxjs/add/observable/from';
import {Observable} from 'rxjs/Observable';

Setup your spy:

const loginResult = '';
const spy = spyOn(authService, 'login').and.callFake(() => {
    return Observable.from([loginResult]);
})

Call login:

fixture.componentInstance.login();

Assert:

expect(spy).toHaveBeenCalled();
Share:
58,097
Kokulan
Author by

Kokulan

Updated on September 06, 2020

Comments

  • Kokulan
    Kokulan almost 4 years

    I have a spec code to test like this

     it('login test', () => {
    
          const fixture = TestBed.createComponent(component);
          fixture.detectChanges();
          let authService = fixture.debugElement.injector.get(Auth);
          spyOn(authService, 'login').and.returnValue('');
    
          const elements = fixture.nativeElement;
          fixture.componentInstance.login();
          expect(authService.login).toHaveBeenCalled();
        });
    

    and the implementation code like this

    login() {
    
        this.auth.login(this.username, this.password).subscribe(() => {
    
          }
        });
      }
    

    it gives error:

    this.auth.login(...).subscribe is not a function

    Why does this error happen?