Solution - Subscription
Solution
import { TestScheduler } from 'rxjs/testing';
describe('getting started with RxJS testing with marbles', () => {
let testScheduler: TestScheduler;
beforeEach(() => {
testScheduler = new TestScheduler((actual, expected) =>
expect(actual).toEqual(expected)
);
});
test('subscribe', () => {
testScheduler.run(({ hot, expectObservable }) => {
const values = {
a: 0,
b: 1,
c: 2
};
const source = hot('100ms a 99ms b 99ms c|', values);
const subscription1 = ' 200ms ^ 100ms !';
const subscription2 = ' 300ms ^';
const expected1 = ' 200ms b 99ms c';
const expected2 = ' 300ms c|';
expectObservable(source, subscription1).toBe(expected1, values);
expectObservable(source, subscription2).toBe(expected2, values);
});
});
});
Let's review the solution above:
- A new instance of the
TestScheduler
is created in thebeforeEach()
method. - Within the test, we invoke the
run()
method on theTestScheduler
instance, and provide the callback function. We use object destructuring to define block-scoped variables for thehot
andexpectObservable
properties of theRunHelpers
object. - For clarity, I've decided to declare the
values
object that represents the values of the next notifications for the source Observable. - We create the
source
Observable using thehot()
function. We progress the virtual time by 100 milliseconds (or 100 frames) and then emit the value represented bya
. The first value of '0' is emitted on frame 100. This is because the first frame is frame0
, which is necessary for testing a synchronous Observable. Then, we progress the virtual time by 99 milliseconds (or 99 frames), and then emit the value represented byb
. Again, we progress virtual time by 99 milliseconds (or 99 frames), and then emit the value represented byc
. Finally, the completion notification emits on frame 301. - The first subscription is represented by
subscription1
. After 200 milliseconds the Observer subscribes to the hot Observable. Then, after an additional 100 milliseconds the Observer unsubscribes. - Let's skip to the expectation for the first Observer, which is represented by
expected1
. First, we progress virtual time by 200 milliseconds (or 200 frames). Again, remember that the frames are 0-based. So, on frame 200 we expect a next notification of the value represented byb
. Then, we progress virtual time by 99 milliseconds (or 99 frames), and then emit the value represented byc
. We do not expect the first Observer to receive the completion notification from thesource
Observable in frame 301. This is because the Observer unsubscribed in frame 300. - Now, let's go back and revisit the second Observer that is represented by
subscription2
. After 300 milliseconds the Observer subscribes to the hot Observable. The second Observer next unsubscribes from the Observable. - We expect the behavior of the second Observer as defined in the
expected2
string. In this instance we progress virtual time by 300 milliseconds (or 300 frames). On frame 300 (again frames are 0-based) we expect a next notification from thesource
Observable of the value represented byc
. Finally, on frame 301 we expect the Observer to receive the completion notification.