I want to test a method inside an Angular 2 component that subscribes to an observable that returns from a method in the service. Below is the code for the service method:
public create(user: User): Observable<any> { return this.http.post(this._api.create, JSON.stringify(user), { headers: this.apiConfig.getApiHeaders() }).map((res: Response) => res.json()); }
It is easy to unit test this method because it returns the observable, so I can just subscribe to it. But I want to test a method in a component that has already subscribed to this:
public onSubmit(user: User): void { this._authentication.create(user).subscribe((token) => { localStorage.setItem('token', token); this.router.navigate(['/Home']); }); }
Here is my specification so far, but when I try to look into localStorage.setItem, it returns as not being called. I understand that he probably checks to see if he was called before his actual call.
it('Should login a user and on success store a token in localStorage', injectAsync([TestComponentBuilder], (tcb) => { return tcb.createAsync(Login).then((fixture) => { let instance = fixture.debugElement.componentInstance; localStorage.clear(); spyOn(localStorage, 'setItem'); instance.onSubmit({userId: ' some@email.com ', password: 'password', siteName: 'sample'}); expect(localStorage.setItem).toHaveBeenCalled(); }); }) );
I am wondering if I need to catch this._authentication.create method in order to return a new observable using a mock response?
After several studies, several articles showed that I need to excuse the service and return Observable.of (), which works synchronously to solve the problem, copy the code below. It still doesn’t work, I work on it most of the day, I don’t feel that it should be so difficult, any help was appreciated.
class MockAuthentication extends Authentication { public create(user: Object): Observable<any> { return Observable.of({'test': 'test'}); } }
angular jasmine rxjs
Homebrew
source share