Blog / Tech / Angular

Angular Marble Testing: A Brief Introduction

  • Rating — 4.8 (39 votes)
  • by Mykola
  • Updated on December 07, 2018
  • Read —
    4-5 minutes
marble testing

Working with Angular implies a wide use of reactive programming, that is, programming with asynchronous data streams. Angular components often operate with several observable streams that have overlapping sequences of values and errors. Testing such scenarios using common methods is often complicated. RxJS Marble Testing is much more helpful in these cases.

In this article, we’ll try to explain what is marble testing and how it works.

  1. What is marble testing?
  2. ‘Jasmine-marbles’ library
  3. Example

What is marble testing?

Marble testing allows you to test asynchronous RxJS code synchronously and step-by-step with the help of RxJS TestScheduler test utility and using virtual time steps.

There are also marble diagrams which demonstrate what is happening with a particular operation in the observable stream.

angular marble testing

ASCII marble diagrams are an alternative way to describe the observable stream. For instance, ASCII diagram a–bc—d–#–| corresponds to the marble diagram on the image above.

A marble diagram in TestScheduler is a string of characters that represents events which occur during the virtual time. Time progresses through ‘frames’. The first character represents a zero ‘frame’ or the beginning of time.

  • “-” — 10 ‘frames’ of time passing
  • “|” — the successful completion of the observable stream. Corresponds to the complete() method.
  • “#” — the error completion of the observable stream. Corresponds to the error() method.
  • “a” (or any other alphanumeric character) — a value emitted by the observable stream. Corresponds to the next() method.
  • “()” — a grouping of several events that should occur synchronously in one ‘frame’. Allows you to group the emitted value with the end of stream or an error.
  • “^” — a subscription point (only for hot observables). It’s a ‘zero frame’ for the observable, so each frame before ^ will be negative. Negative time may be needed during ‘ReplaySubjects’ testing.
  • “!” —  the end of a subscription point.

ASCII marble diagrams are used to create so-called hot and cold observable streams, which, in their turn, are used as mock-ups in test-waiting methods. Let’s discuss this next.

Jasmine-marbles library

‘Jasmine’ provides the ‘npm’ package ‘jasmine-marbles’. It is a library for `TestScheduler` that significantly simplifies marble testing. This package is not included in the Angular CLI test suite, so it must be installed separately: ‘$ npm install jasmine-marbles –save-dev’

‘Jasmine-marbles’ provides two methods for creating observables out of marble diagrams:

  • ‘cold (marbles: string, values ?: object, errors ?: any)’ – the subscription starts when the test begins
  • ‘hot (marbles: string, values ?: object, errors ?: any)’ – it’s already “running” when the test begins; the subscription starts with the “^” character.

ASCII marble diagram is passed to both methods as the first argument. The second argument is an optional object matching the characters in the diagram and their values. If this object is absent, the created observable will be emitting the characters from the diagram. If there is an error in the stream, it will be passed as the third argument.

For instance, ‘cold(‘–a–b–|’, {a: 10, b: ‘hello’})’ will create a cold observable stream that will emit value 10 at 30ms, value ‘hello’ at 60ms and will end at 90ms.

Thanks to the work of the test scheduler, the test is synchronous (`fakeAsync ()` is not used).

Example

Let’s take a look at a common example – a counter component.  

We have the following requirements to the component:

  1. The component must have two buttons (‘Up’ and ‘Down’) and a counter.
  2. The counter should start at 0.
  3. Clicking the ‘Up’ button should add 1 to the counter; clicking the ‘Down’ button should subtract 1 from the counter.

Now, let’s create a component test considering the above requirements:

marble testing code

Next, we need to describe the logic behind the way the component works with the observable stream using marble diagrams:

  1. Stream of events after pressing the ‘Up’ button
  2. Stream of events after pressing the ‘Down’ button.
  3. The resulting stream.

Now, based on the marble diagrams, let’s create the observable streams using the ‘cold ()’ method from the `jasmine-marbles` library. We need this to verify whether the resulting observable stream of the counter corresponds to the observable streams of click events on the ‘Up’ and ‘Down’ buttons.

After that, we can implement a component code that will successfully pass the tests.

import { Component } from '@angular/core';
import { merge, Observable, Subject } from 'rxjs';
import { mapTo, scan, startWith } from 'rxjs/operators';

@Component({
 selector: 'app-counter',
 template: `
   <button (click)="up$.next()">Up</button>
   <button (click)="down$.next()">Down</button>
   <div class="counter">{{counter$ | async}}</div>
 `,
})
export class CounterComponent {
 counter$: Observable<number>;
 up$ = new Subject();
 down$ = new Subject();

 constructor() {
   const {up$, down$} = this;
   this.counter$ = this.getCounter({up$, down$});
 }

 getCounter({up$, down$}) {
   return merge(
     up$.pipe(mapTo(1)),
     down$.pipe(mapTo(-1))
   ).pipe(
     startWith(0),
     scan((x, y) => x + y)
   )
 }
}

To receive a whole code from this article, fill out the form below and click Send Download Link button.

Enter your name and email to download the file.

Conclusion

As mentioned, the described methodology is indeed very effective and it’s the best option for testing asynchronous RxJS code. It will help you easily test even the most complex networks of observable streams in various Angular components of the application.

Looking for professional app developers for your next project?

Mykola Mykola is a web developer at GBKSOFT. His professional experience includes 10+ years of software development with a focus on Angular and React in recent years. Mykola’s hobby is to learn rare features and share his knowledge with the tech community.

Leave a comment
Close

Leave a Reply

Related services

Categories

All articles Business Company News Marketing Tips Our Awards StartUp App Ideas Tech Tech News Review UI and Design
GBKSOFT Team
A-mazed to meet you!
We are GBKSOFT software company.
Thanks a lot for reading your blog
Since 2011 we create ambitious software projects from scratch.

You've got
a project in mind

What's next?

Send us a message with a brief description of your project.
Our expert team will review it and get back to you within one business day with free consultation and next steps.

Testimonials

Nothing can be better than getting a review from our happy clients
who recommend us and trust us their business.

Aaron
I’ve been using GBK Soft for the past 3 years and they have been great. Communication is unparalleled to other app development companies. I’ve continued to return to them to improve my iOS app countless times and I will continue to do so in the future. I highly recommend this company! Improve
Andy
I think they do great work. I haven’t yet given them something that they were unable to do. Great
Raphael
My Project with GBKSOFT gave me the ability to develop my software while keeping a busy schedule. Ana, who was my project manager, was very professional and was always understanding of my vision and what I wanted. I would recommend GBKSOFT again to any other company or person who has a vision for their web application. Thank you GBKSOFT! Recommend
Jonathan
More good work from team GBKSOFT. All well executed. The support within GBKSOFT is excellent. Communication is good too, spoken English as well as written. Support
Gireesh, USA
One word...EXCELLENT.
Very well thought out and articulate communication. Clear milestones, deadlines and fast work.Patience. Infinite patience. No shortcuts. Even if the client is being careless (me). The best part...always solving problems with great original ideas, especially with this strange project where we are making up new words every day!
Excellent
Tao
GBKSOFT did a good job to manage the project. They put in a good effort to communicate with us and make it easier for us to communicate with developers. Good Job
Devan
They write clean code, adhere to deadlines, and communicate extremely well. I strongly recommend anyone from the GBKSOFT agency and hope to work with them again myself. Clean Code
Garrett
They proved to be very good and they’re very reliable as well. They are quite conscientious. They will go the extra yard to make sure we're happy. Reliable
Dave
GBKSOFT’s performance has been very strong. We've referred them twice, which says all anyone needs to know about them. A referral is the ultimate signal we can give that these guys are great. Strong
19
spinner