Test asynchronous Observables as if they were synchronous!

Photo by Sharon Pittaway on Unsplash

If you have worked with Angular (2+) you must have used Observables. In fact, the implementation Angular uses — RxJs is tightly incorporated in the foundations of the framework itself for stuff like Routing and Http.

If you want to learn more about Observables and how to use them, you can refer to Gerard Sans’s cool post about RxJs below.

We all know (I hope so) that we should test our code but we also know that testing async code could be cumbersome, especially when dealing with a complex subject like Observables.

For example, we could have the following method:

Here, we return a flat array and intentionally delay it by 500ms.

How are we going to test this?

Will this work? It’s obvious that it won’t, since our test runner would not know when to execute its assertions and will just exit, before the 500ms delay has passed.

To solve this, we can just use the done callback and instruct the test runner when to execute its assertions, like:

This will work, but for some reason you don’t like it, right? It’s a bit verbose, it has nesting and an extra callback to call every time.

Can we do it better?

Of course we can, this is Javascript, you can do anything!

I present you a simple helper function which will receive a stream (Observable) and a skipTime. It will subscribe to the observable, assign it’s value to a local variable, skip some time and return the value.

Wait, what? You can’t do that!

How does jasmine.clock.tick() work?

It basically mocks time-based APIs with custom functions which make those calls synchronous and also let you “progress” in time by ticking .

You will also need to install jasmine’s clock before each test and uninstall it after, like:

Ok, but how do I use that?

Cool, huh? Synchronous, linear, easy!

You can see more use-cases in the ngx-cacheable’s tests here. Also if you haven’t read my previous article about the simple cache decorator, please do: