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

Popular posts from this blog

scala - 'wrong top statement declaration' when using slick in IntelliJ -

c# - DevExpress.Wpf.Grid.InfiniteGridSizeException was unhandled -

PySide and Qt Properties: Connecting signals from Python to QML -