tl;dr is it possible to unit test this code without rewriting it?
http://jsbin.com/jezosegopo/edit?js,console
const keyUpObserver = ($input, fetchResults) => {
const source = Rx.Observable.fromEvent($input, 'keyup')
.map(e => e.target.value)
.filter(text => text.length > 2)
.debounce(300)
.distinctUntilChanged();
return source.flatMapLatest(text => Rx.Observable.fromPromise(fetchResults(text)));
};
keyUpObserver
in the above code is heavily based on the RxJS autocomplete example, and uses a debounce to prevent hammering the server.
I'm trying to unit test this function, but Sinon's useFakeTimers doesn't appear to be working.
const clock = sinon.useFakeTimers();
const $input = $('<input>');
const fetchResults = (text) => new Promise(resolve => resolve(text + ' done!'));
keyUpObserver($input, fetchResults).subscribe(text => console.log(text));
$input.val('some text').trigger('keyup');
clock.tick(500);
// Enough time should have elapsed to make this a new event
$input.val('some more text').trigger('keyup');
I'm guessing this isn't sinon-related either, rather that RxJS uses some internal clock which must be unaffected by an external fake clock.
Given that, is there anyway to unit test my keyUpObserver code without rewriting it to also take a scheduler (default in production, test in unit tests)?
...to approach an answer: it seems that RxJs is using the default/global setTimeout
implementation which Sinon should be able to overwrite. At least that's what I'd say from reading the defiultscheduler's
code which it uses if you don't pass (as mentioned) an custom scheduler.
Still, I am a bit confused about the intend. From this little fork I'd expect only the 3rd trigger to actually fire something which it does or am I should out of line? 👀
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