Say that you created a service that essentially wraps Angular’s HttpClient calls:
And say that you called that in a component:
And now you want to test the Get function to make sure that myValue is set to the value returned by the service. If you try to create a spy on the function in MyService, you’ll find that the code is executed properly – that is, the value is set (you can put logging statements around and see it working), but any expect assertions you do will fail. This is because the Observable is asynchronous, but your test is synchronous. Here’s the working spec file, but I’ll go into more detail below.
The first key is to make the test function async. This is so Jasmine knows that the function contains callbacks.
Next, include Observable and ‘rxjs/add/observable/of’. (Note that you need the ‘rxjs/add/observable/of’ to get the .of() function on your Observable). This will let you create an Observable (which is returned by your service) to spy on. Create the spy on the function using spyOn, which will replace the contents of the function with something else (namely returning Observable.of()), but also allow you to watch and assert on that function.
Finally, wrap your assertions in
fixture.whenStable().then(() => {
});
This signals Jasmine that there is something that is in a callback, and the test runner will wait until all of the callbacks have been received before ending the test.
Unit testing error paths of Observable<T> – Darchuk.NET
[…] the last post I wrote about how to mock up and test Observable<T> in Jasmine so that you can properly […]
Testing Observables in Angular >= 6.0.0 – Darchuk.NET
[…] a previous post I talked about testing Observables in your Angular code. This is pretty common, because […]