LiveLoveApp logo

Solution - First Test

Solution

import { TestScheduler } from 'rxjs/testing';
import { map } from 'rxjs/operators';

describe('getting started with RxJS testing with marbles', () => {
  let testScheduler: TestScheduler;

  beforeEach(() => {
    testScheduler = new TestScheduler((actual, expected) =>
      expect(actual).toEqual(expected)
    );
  });

  test('map values for the 10x developer', () => {
    testScheduler.run(({ cold, expectObservable }) => {
      const values = {
        a: 1,
        b: 10
      };
      const source = cold('1000ms a', values);
      const expected = '   1000ms b';
      expectObservable(source.pipe(map((value) => value * 10))).toBe(
        expected,
        values
      );
    });
  });
});

See example on codesandbox

Let's review the solution code above:

  • First, we set up the TestScheduler in the beforeEach() method.
  • In our first test we are asserting the values emitted by the source Observable 10x, since, well, we're all 10x developers here.
  • We invoke the run() method on the TestScheduler instance, which takes a callback function that is invoked with the RunHelpers object. Using object destructuring we obtain the cold() and expectObservable() functions.
  • Within the callback function we define the values object.
  • We then create a new cold Observable using the cold() function, specifying the marble string along with the values for the next notifications.
  • The expected marble string represents the expected behavior that we'll assert in the test.
  • Finally, we invoke the expectObservable() function, providing the source Observable. Using the map() in the source Observable's pipe we map each next notification value to the value multiplied by 10. The expectObservable() returns an object containing a single toBe property. Using chaining we invoke the toBe function and specify the expected marble string, and the values for the expected next notifications.