I want to test the error handling in my Angular2 component and therefore want to mock a service to return an Observable.throw('error'). How can that be done using Jasmine and Karma and Angular 2?
-
1can you provide us a code example? to add a context to your question an allow us to provide a precise answer. – Supamiu Dec 05 '16 at 08:38
4 Answers
Here is my solution for the ones using Rxjs 6
let mockService = {
getData: () => {
return of({data:'any data'});
}
}
spyOn(mockService , 'getData').and.callFake(() => {
return throwError(new Error('Fake error'));
});

- 361
- 3
- 4
-
1
-
8This can be shorter `let mockService = { getData: of({data:'any data'})}; spyOn(mockService , 'getData').and.returnValue(throwError(ERROR_RESPONSE))` – Ron Jonk May 14 '19 at 15:40
You should create
an observable, and just call the observer error
. For example
let mockService = {
error: false,
data: 'something',
getData: () => {
return Observable.create(observer => {
if (this.error) {
observer.error(new Error(..))
} else {
observer.next(this.data);
}
observer.complete();
})
}
}
Now for your tests, you can use the mock for both success cases and error cases. For an error case, just set the error
property to true. In the success case, next
is called with the data.
When you subscribe to an observable, you can pass three callback, success
, error
, and complete
service.getData().subscribe(
(data) => {} // sucess
(error) => {} // error
() => {} // complete
)
So with the observer
, when calling observer.next
, observer.error
, observer.complete
, the corresponding callback will be called.

- 205,037
- 37
- 486
- 720
-
I'm having a little trouble with this one. Is it in the test declaration ie "it" that I set the property to "true"? When I set the property to "true" the change is not picked up on in the test declaration I'm setting it in. I could put my code in a plnkr if this would help. – bmd Jul 13 '17 at 09:49
-
You can simply mock Observable
and throw error object using Observable.throw({status: 404})
and test error block of observable.
const xService = fixture.debugElement.injector.get(SomeService);
const mockCall = spyOn(xService, 'xMethod')
.and.returnValue(Observable.throw({status: 404}));
Here I am throwing http 404
error from Observable.throw({status: 404})
by mocking xMethod
of xSerive
in my test.

- 20,520
- 23
- 96
- 132
-
6In Rxjs 6+, `Observable.throw` is changed to the static operator `throwError`. – Koja Dec 04 '18 at 14:15
-
In `RxJs 6+` you don't have to import the whole observable, you just do with `throw()` – Aniruddha Das Dec 04 '18 at 18:03
Simplified version for RxJS 6:
let mockService = {
getData: () => {
return of({data:'any data'});
}
}
spyOn(mockService , 'getData').and.returnValue(throwError('test error'));

- 8,585
- 14
- 54
- 67