4

I'm moderately new to RxJS and very new to unit testing with Jest and I've run into a pretty confusing problem when trying to test some mocked-up RxJS observables.

In order to mimic a data stream, I created an Observable in a test spec.js file like this:

var Rx = require("rx");

var source = Rx.Observable.interval(500).take(10);

source.subscribe(
    function(x){ console.log(x) },
    function(e){ console.log(e) },
    function(){ console.log('completed') }
  );

Although this logs correctly when just ran as a node script, it doesn't log anything when ran through npm test. The Observable.delay and setTimeout functions don't appear to work as well.

skyboyer
  • 22,209
  • 7
  • 57
  • 64
jdpigeon
  • 391
  • 4
  • 8

1 Answers1

3

Here's what worked for me:

var Rx = require("rx");

describe("Interval Test", () => {
  const source = Rx.Observable.interval(100);
  let count = 0;
  source.subscribe(
  x => count++,
  e => console.log("error: ", e),
  () => console.log("complete"));

  it("run for 1 second", done => {
    setTimeout(() => {
      console.log('one second passed');
      expect(count).toBe(10);
      done();
    }, 1010)
  });
});

It seems like I needed to put a timeOut in my it test function in order for this async observable to be able to execute. Also really important was the done() call in order to prevent the time from running indefinitely.

Note: Alternately, if you want to use Jest's fake time to control timing manually, that seems to work as well. I find that I did not need to use the VirtualTimeScheduler.

jest.useFakeTimers();    
var Rx = require("rx");

var source = Rx.Observable.interval(500).take(10);

source.subscribe(
    function(x){ console.log(x) },
    function(e){ console.log(e) },
    function(){ console.log('completed') }
  );
jest.runAllTimers();
jdpigeon
  • 391
  • 4
  • 8