Last active
July 23, 2022 22:20
-
-
Save malkab/3e680ce6d2c83b3939c254e84753028a to your computer and use it in GitHub Desktop.
Testing Observables with Mocha
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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