Marble testing with RxJS testing utils

You don’t need a third-party library for marble testing

Kevin Kreuzer
Aug 6 · 5 min read

Once you start your path to master Observables, the chances are high that you already encountered a marble diagram on your way.

The marble syntax is a very intuitive syntax to represent streams, and it is often used to visualize observable transformations. It is not only a form of documentation, but it can also be used to test our Observables.

From consulting various developers, I have seen that teams often take advantage of a third-party library to apply marble testing. Using a third-party library is a valid approach, and there’s nothing wrong with it. But!

You can actually “marble test” without using a third-party library! 🤩

What this blog post is about

This blog post shows you how to “marble test” without a third-party library. It assumes that you’re already familiar with the marble syntax and marble testing itself.

If you have never written a marble test before you might want to check out this great introduction from Benjamin Cabanes

Marble testing without a third-party library

Ok, you are telling me that I can marble test without a third party library? Why did we then use a third-party library in the first place? 🤔

In most cases, teams use a third-party library due to legacy reasons or missing documentation. Legacy? I mean RxJS version 5. Yes, JavaScript evolves fast.

When you want to write marble tests in RxJS version 5, it makes complete sense to use a third-party library. The RxJS testing utilities of version 5 were only meant to be used internally by the RxJs core team and not for developers to test their application.

However, with version 6 the RxJs team has improved the testing utilities for developers. You can now use them to test your application. In a nutshell:

Since RxJS version 6 you can use the testing utils to apply marble testing!

How cool is that? 🤯 Well, it’s pretty cool.

“Ok, but it already works with our third-party library, why should we switch?” is probably what you may think right now. Here’s the point.

If something can be achieved natively and doesn’t introduce too much overhead, shouldn’t we try to prefer it over a third-party lib?

People will answer this question in different ways. In my opinion, it’s a good habit to get rid of third party dependencies due to the following reasons.

  • You are always up to date with the core implementation.
  • You are up to date with the latest features.
  • A dependency less — maybe a little bit niggly but I think it makes projects more understandable on a first look at package.json.

In the end, it’s up to you to make this decision. But let’s now have a look at how we can apply marble testing using RxJs testing utils only.

TestScheduler and RunHelpers

To “marble test” we need to use Rx’s TestScheduler. The TestScheduler has a run method which we can call with a callback.

The callback accepts a parameter of a RunHelpers type which gives us all the helper methods we need for marble testing.

RunHelpers interface from the RxJs repo.

The interface contains the following methods:

  • cold/hot: creates a cold/hot Observable based on a given marble diagram. Accepts a marble diagram as a first parameter and values and errors as additional optional parameters. If we create a hot Observable, the ^ can be used to indicate the “zero frame.”
  • flush: starts a virtual time. Only needed if you use helpers and RxJs testing tools outside the run callback or if you want to flush more than once.
  • expectObservable: used to assert that an Observable meets a marble diagram.
  • expectSubscriptions: used to assert that an Observable has the expected subscriptions.

Getting started with Rx’s TestScheduler

To write a marble test with Rx’s TestScheduler the following steps are required.

  1. Import TestScheduler from rxjs/testing.
  2. Instantiate it in a beforeEach hook and pass a assertDeppEqual function which tells the TestScheduler how to compare values. The methods used to compare values depends on your testing framework.
Instantiation of RxJs’s TestScheduler with the use of Jasmines beforeEach hook

3. Use the TestScheduler in your tests by calling it’s run method and pass a callback to it. Remember, the callback needs to accept the RunHelpers as the first parameter.

4.Tipp! Instead of using the runhelpers directly I find it quite nice to destructure the helpers into variables and use them directly to implement your marble test.

Nice! That’s it. Let’s have a look at the complete test setup.

Conclusion

The RxJs testing utils have evolved.

While the testing utils in version 5 were only built for internal usage, they are now improved for external usage. Which means you can now use them to test Observables in your application.

Even though the current third party libraries are great — you actually don’t need them.

🧞‍ 🙏 If you liked this post, share it and give some claps👏🏻 by clicking multiple times on the clap button on the left side.

Claps help other people to discover content and motivate me to write more 😉

Feel free to check out some of my other articles about front-end development.

Kevin Kreuzer

Written by

Passionate freelance frontend engineer. ❤️ Always eager to learn, share and expand knowledge. 🧐 Co-founder at trasier.com — distributed business tracing tool

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade