简体   繁体   中英

How to write a marble test for a combineLatest Observable?

I have an observable that takes two Observable<boolean> and runs an "or" operation on them with combineLatest .

interface LoadingEventEmitter {
  isLoading$: Observable<boolean>
}

export class LoadingService {
  isLoading$: Observable<boolean>;

  constructor(
    private requests: LoadingEventEmitter,
    private lazyRoutes: LoadingEventEmitter
  ) {
    this.isLoading$ = combineLatest([
      this.requests.isLoading$,
      this.lazyRoutes.isLoading$,
    ]).pipe(
      map(
        ([requestsLoading, lazyRoutesLoading]) =>
          requestsLoading || lazyRoutesLoading
      )
    );
  }
}

I'm trying to test it with jasmine-marbles .

fdescribe('LoadingService', () => {
  const createLoadingService = (
    requests$: Observable<boolean>,
    lazyLoading$: Observable<boolean>
  ) => {
    const mockRequests = { isLoading$: requests$ };
    const mockLazyLoading = { isLoading$: lazyLoading$ };

    return new LoadingService(mockRequests, mockLazyLoading);
  };

  const values = { t: true, f: false };

  it('isLoading$ should be true when at least one of the sources emits true', () => {
    const a = cold('---t---f---f---', values); // First source
    const b = cold('f----t---------', values); // Second source
    const c = cold('---t-t-t---t---', values); // Result

    const service = createLoadingService(a, b);

    expect(service.isLoading$).toBeObservable(c);
  });
});

The test looks fine to me, but it fails with the following error:

Expected $[0].notification to be a kind of Notification, but was Object({ kind: 'N', value: true, error: undefined }).
Expected $[1].notification to be a kind of Notification, but was Object({ kind: 'N', value: true, error: undefined }).
Expected $[2].notification to be a kind of Notification, but was Object({ kind: 'N', value: true, error: undefined }).
Expected $[3].notification to be a kind of Notification, but was Object({ kind: 'N', value: true, error: undefined }).

What does that error mean and how do I fix it?

I managed to do it with rxjs-marbles :

  it(
    'isLoading$ should be true when at least one of the sources emits true',
    marbles((m) => {
      const a = m.cold('---t---f---f---', values);
      const b = m.cold('f----t---------', values);
      const c = '     ---t-t-t---t---';

      const service = createLoadingService(a, b);

      m.expect(service.isLoading$).toBeObservable(c, values);
    })
  );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM