Testing RxJS timers with Jest

·
·2 min read

Testing RxJS has always been a challenge for me, especially when using timers. Some testing utilities (such as Angular's) make it easier - others not so much.

Jest, though, didn't make me miss Angular's utilities much; I didn't find too much online, and StackOverflow's answers led to more questions. So this is for you, and the future me.

Testing a simple timer stream with Jest's timers

Let's write a dead-simple RxJS operator which emits a value every 100 milliseconds. We will test that it emitted 5 times in 499 milliseconds, no more, and no less.

When we want to use Jest's timers, we need to enable such functionality:

jest.useFakeTimers();

Let's create a simple function tick to advance by a certain number of ms:

const tick = (ms = 0) => {  
	jest.advanceTimersByTime(ms);
};

By default, it advances by 0 milliseconds.

And now, on to the test.

We can use Jest's mock to count the times they have been called.

// a simple mock

const fn = () => jest.fn(() => 1);

Now, nothing special, we will create the timer stream; it starts from 0 and advances every 100 milliseconds:

const stream$ = timer(0, 100).pipe(
  tap(fn),
);

And here is the full test:

it('emits 5 times', async () => {
  const fn = jest.fn(() => 1);
  const stream$ = timer(0, 100).pipe(tap(fn));

  // subscribe to the stream, otherwise it will never execute
  stream$.subscribe();

  // advance time by 499 ms
  tick(499);

  // expect the spy "fn" to have been called 5 times
  expect(fn.mock.calls.length).toEqual(5);
});

And here is proof :)

Test running in WebSorm


Articles about
RxJsRxJs

Cover Image for A Reactive Enum with Typescript and RxJs
·5 min read·
RxJsRxJs

Typescript's template literals' types allow us to generate dynamic and typed code, together. In this article, I want to show how we can build a dynamic reactive enum with TS and RxJS

Cover Image for Caching RxJS streams into Web Storage
·8 min read·
RxJsRxJs

In this article I will introduce you to a simple utility that allows you to cache RxJS streams in memory or the browser's storage

Cover Image for 5 common mistakes with RxJS
·6 min read·
RxJsRxJs

A list of common mistakes while using RxJS, and explanations on what to do instead

Cover Image for RxJS Subjects in Depth
·7 min read·
RxJsRxJs

Learn how RxJS Subjects are used in real-world applications

Cover Image for RxJS Patterns: Efficiency and Performance
·10 min read·
RxJsRxJs

A rundown of all RxJS operators and techniques you can leverage to avoid needless computation and make your code snappier and faster

Cover Image for A simple Countdown with RxJS
·5 min read·
RxJsRxJs

In this tutorial, we’re going to build a very simple timer application with only a few lines of code using RxJS