jasmine - How to test observable containing a debounce operator? -
how 1 write jasmine test test observable debounce
operator? i've followed this blog post , understand principles of how should tested, doesn't seem work.
below factory using create observable:
import rx "rx/dist/rx.all"; import domfactory "../utils/dom-factory"; import usernameservice "./username.service"; function createusernamecomponent(config) { const element = domfactory(config); const username = rx.observable .fromevent(element.find('input'), 'input') .pluck('target', 'value') .startwith(config.value); const isavailable = username .debounce(500) .tap(() => console.info('i never called!')) .flatmaplatest(usernameservice.isavailable) .startwith(false); const usernamestream = rx.observable.combinelatest(username, isavailable) .map((results) => { const [username, isavailable] = results; return isavailable ? username : '' }) .distinctuntilchanged(); return object.freeze({ stream: usernamestream, view: element }); } export default createusernamecomponent;
note tap
operator never called test. however, executed if run code on browser.
below attempt @ test:
import rx "rx/dist/rx.all"; import username "./username.component"; import dataitembuilder "../../../test/js/utils/c+j-builders"; import usernameservice "./username.service" describe('username component', () => { let input, username; beforeeach(() => { const usernameconfig = dataitembuilder.withname('foo') .withprompt('label').withtype('text').build(); const usernamecomponent = username(usernameconfig); usernamecomponent.stream.subscribe(value => username = value); input = usernamecomponent.view.find('input'); }); it('should set valid username after debounce', () => { const scheduler = injecttestschedulerintodebounce(); scheduler.schedulerelative(null, 1000, () => { dokeyuptest('abcddd', 'abcdd'); scheduler.stop(); }); scheduler.start(); scheduler.advanceto(1000); }); function injecttestschedulerintodebounce() { const originaloperator = rx.observable.prototype.debounce; const scheduler = new rx.testscheduler(); spyon(rx.observable.prototype, 'debounce').and.callfake((duetime) => { console.info('the mocked debounce never called!'); if (typeof duetime === 'number') { return originaloperator.call(this, duetime, scheduler); } return originaloperator.call(this, duetime); }); return scheduler; } function dokeyuptest(inputvalue, expectation) { input.val(inputvalue); input.trigger('input'); expect(username).tobe(expectation); } });
when run test, fake debounce
never gets called. plan mock username
service once can past debounce
.
in test code triggering input event inside schedulerelative
function. doesn't work because advancing 1000ms before doing change. debouncer waits 500ms debounce isavailable
call stopped scheduler time not advancing afterwards.
what should is: trigger input event before advancing scheduler time or better in schedulerelative
function time <= 500ms in , inside schedulerelative
function 1000ms have call expect
function expected output , stop scheduler.
it should this:
it('should set valid username after debounce', () => { const scheduler = injecttestschedulerintodebounce(); scheduler.schedulerelative(null, 500, () => { input.val(inputvalue); input.trigger('input'); }); scheduler.schedulerelative(null, 1000, () => { expect(username).tobe(expectation); scheduler.stop(); }); scheduler.start(); scheduler.advanceto(1000); });
in addition have better experience scheduleabsolute
instead of schedulerelative
because less confusing.
Comments
Post a Comment