I have a webapp project which uses rxjs5 to implement a flux and I am currently looking for solutions to write unit tests on it.
In fact, I have implemented custom observables inside, for example :
function getActivityObservable(events, timeout) {
return Observable.create((observer) => {
const deb = debounce(() => observer.next(false), timeout || DEFAULT_TIMEOUT);
const sub = events.subscribe((e) => {
if (!e) {
deb.cancel();
observer.next(false);
} else {
observer.next(true);
deb(e);
}
});
return () => {
if (sub) sub.unsubscribe();
if (deb) deb.cancel();
};
}).distinctUntilChanged();
}
I would like to test it using the marble testing way and write something like (i took a sample example from rxjs repository)
describe("getActivityObservable", () => {
it("should debounce by selector observable", () => {
const e1 = hot("--a--bc--d----|");
const e1subs = "^ !";
const expected = "----a---c--d--|";
expectObservable(e1.debounce(getTimerSelector(20))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});
My question is:
Is it possible to use marble testing method (with operators like hot
, cold
and so on...) outside the rxjs5 project. I don't figure out how to use this nice tool in my project.
Thank you for your help.
You can but as Ben comment: "it's not very ergonomic".
I'm using mocha and monkey patching it
:
const isEqual = require('lodash.isequal');
const TestScheduler = require('rxjs/testing/TestScheduler').TestScheduler;
const assertDeepEqualFrame = (actual, expected) => {
if (!isEqual(actual, expected)) {
throw new Error('Frames not equal!');
}
}
const oit = global.it;
global.it = function(description, cb, timeout) {
if (cb.length === 0) {
oit(description, function() {
global.rxTestScheduler = new TestScheduler(assertDeepEqualFrame);
cb();
global.rxTestScheduler.flush();
});
} else { // async test
oit.apply(this, arguments);
}
};
I have taking a lot of inspirations from ngrx/store and especially this file: https://github.com/ngrx/store/blob/master/spec/helpers/test-helper.ts
and then can I write my test like:
it('should filter with an always-true predicate', () => {
const source = hot('-1--2--^-3-4-5-6--7-8--9--|');
const expected = '--3-4-5-6--7-8--9--|';
const predicate = () => { return true; };
expectObservable(source.filter(predicate)).toBe(expected);
});
Edit
You can see how I monkey patch it
here: https://github.com/tjoskar/ng2-lazyload-image/blob/5e1c64a3611530ce26857a566b2d76dff890a3c5/test/helpers/test-helper.ts
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With