Skip to content

Instantly share code, notes, and snippets.

@malkab
Last active July 23, 2022 22:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save malkab/3e680ce6d2c83b3939c254e84753028a to your computer and use it in GitHub Desktop.
Save malkab/3e680ce6d2c83b3939c254e84753028a to your computer and use it in GitHub Desktop.
Testing Observables with Mocha
import "mocha";
import * as rx from "rxjs";
import * as rxo from "rxjs/operators";
import { expect } from "chai";
/**
Testing Observables with Mocha
Testing observables with Mocha can be extremely tricky. In this code
fragments examples are shown that has worked well in the past.
There are two tests:
- one test all outputs emitted by the observable in the complete method,
being able to test intermediary results in the pipe() chain;
- the other test the observable outputing an error.
*/
// This clause can be used to add a timeout before each test, if needed.
// However, delay() can be used to add a timeout before certain Observable tests
// when needed
beforeEach(done => setTimeout(done, 1000));
/**
A set of related tests.
*/
describe("Tests", () => {
// Encapsulate each test in an "it" Mocha clause. Note the "done": this is
// used at the COMPLETE callback of the observable to tell Mocha the test is
// really finished. If not used, the test will be finished before the
// Observable completes.
it("Test observable output", (done) => {
// Declare variables to gather data emitted by observable to be latter
// processed at the COMPLETE callback
let out: any[] = [];
// This test need a little bit of delay to allow previous test to complete
// some work not controllable from the test themselves
rx.of("Waiting for something (this should not be necessary").pipe(
// Wait a second...
rxo.delay(1000),
// Fire another piped Observable
// Some of the observables can output multiple results
rxo.concatMap(() => anotherObservable$()),
rxo.concatMap((o: any) => {
// Some Mocha tests can be included here on intermediate observable
// results
expect(o).to.be.equal(0);
return justAnotherObservable$()
})
).subscribe({
// Here data emitted by observable are gathered
next: (o: any) => out.push(o),
// In case there is an error, warn here
error: (error: Error) => {
console.error("ERROR at Test observable output: ", error);
// Not wanting to check errors, so terminating tests.
process.exit(1);
},
// Finally, analyze all emitted values
complete: () => {
expect(out).to.be.deep.equal(something);
// DON'T forget to call done() to instruct Mocha the test
// is really over!
done();
}
})
// A more generous timeout for this test, which is supossed to take longer
}).timeout(500000);
// Here we test the observable outputting errors
it("Test observable error", (done) => {
// Declare variables to gather data emitted by observable to be latter
// processed at the COMPLETE callback
let out: any[] = [];
// This test need a little bit of delay to allow previous test to complete
// some work not controllable from the test themselves
rx.of("Whatever").subscribe({
// Here the data emitted by observable are gathered
next: (o: any) => out.push(o),
// In case there is an error, warn here
error: (error: Error) => {
expect(error.message).to.be("Whatever");
// DON'T forget to call done()!
done();
},
// If the observable reaches here, there was no error, so abort
complete: () => {
console.error("ERROR: Test observable error terminated without errors, should not happen");
// Abort
process.exit(1);
}
})
// A more generous timeout for this test, which is supossed to take longer
}).timeout(500000);
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment