Daria
Daria

Reputation: 41

When you subscribe with rxjs, how do you signal to your test if it fails?

I am a complete beginner. The issue I am having is that once I throw an error in rxjs observable, my test doesn't know about it. When I am subscribing in a test, and it fails within rxjs it just throws an error and I need to notify my test that the error occurred. Here's a more simple example that shows that "test failed" is never printed.

import { sample } from "rxjs/operators";
const source = interval(1000);
// sample last emitted value from source every 2s
// output: 2..4..6..8..
const example = source.pipe(sample(interval(2000)));
async function test_runner() {
    setup();
    try {
        await test();
        console.log("test succeeded");
    } catch (e) {
        console.log("test failed");
    }
}
async function setup() {
    console.log("setup");
    const subscribe = example.subscribe((val) => {
        console.log(val);
        if (val === 4) {  throw Error("error!"); }
    });
}
async function test() {
    console.log("test");
    await waitMs(10000);
}

test_runner();

async function waitMs(waitTime: number): Promise<void> {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve();
        }, waitTime);
    });
}

Is there a way to handle this? I appreciate any help.

Upvotes: 0

Views: 238

Answers (2)

customcommander
customcommander

Reputation: 18941

When you subscribe you can pass functions to:

  • process items emitted by the stream
  • process an error
  • process a completion signal

You can use that in your tests too:

describe('when a stream emits an error', () => {
  it('should call your error handler', () => {
    const stream$ = throwError('wat?!');
    stream$.subscribe({ error: (err) => {
      chai.expect(err === 'wat?!').to.be.true;
    }});
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.5/rxjs.umd.min.js"></script>
<script src="https://unpkg.com/chai/chai.js"></script>
<script src="https://unpkg.com/mocha/mocha.js"></script>
<script>const {throwError} = rxjs;</script>

<div id="mocha"></div>

<script class="mocha-init">mocha.setup('bdd');</script>
<script class="mocha-exec">mocha.run();</script>

Upvotes: 1

satanTime
satanTime

Reputation: 13574

If you want to test rx streams one of the best ways is to use marbles diagram. That's what ngrx uses for effects testing.

https://www.npmjs.com/package/jasmine-marbles https://github.com/ngrx/platform/blob/master/docs/effects/testing.md

With marbles diagram you can write style where you expect emit / error and to assert it.

For example syntax hot('---#') means that after 30ms there's an error in the stream.

Upvotes: 1

Related Questions