Chris
Chris

Reputation: 73

How to test subscription code after pipe(takeWhile(...)) in Angular 7

I'm surprised I haven't been able to find an answer to this despite a lot of searching...

I'm trying to test that my subscription code is doing the right thing. I've done this countless times before in Angular 2, but we just started a new project so we're using the latest Angular which has picked up a re-write of rxjs that changed the chaining to piping and now I have no idea what to mock or how to do it.

Given:

  constructor(private media: MediaObserver) { }

  ngOnInit() {
    this.active = true;

    this.media.media$.pipe(takeWhile((ev) => this.active)).subscribe((change: MediaChange) => {
      if (change.mqAlias === "xs" || change.mqAlias === "sm") {
        this.stackFooter = true;
      } else {
        this.stackFooter = false;
      }
    });
  }

How do I write a karma/jasmine test to make sure that this.stackFooter is being set correctly when the media service fires an event? I tried to spy on various things (media$, "pipe"), for example, but it appears the takeWhile() returns a new Observable which I don't seem to have any access to? How can I test this? Or, is this not a recommended pattern anymore and I should just be doing something else completely?

Upvotes: 1

Views: 3456

Answers (1)

Amir Arbabian
Amir Arbabian

Reputation: 3699

actually it's returning a new Observable, but you do not care about Observable itself you care about the stream that it contains, try to do this:

In your test

let mockMediaSubject: BehaviorSubject<MediaChange>;
...
beforeEach(() => {
   mockMediaSubject = new BehaviorSubject({});
   TestBed.configureTestModule({
      ...
      providers: [ 
         { 
             provide: MediaObserver, 
             useValue: { media$: mockMediaSubject.asObservable() }
         }
      ]
   });
});

...
it("should set stackFooter to true when media$ emits 'xs' as mqAlias", () => {
   mockMediaSubject.next({mqAlias: 'xs'});

   expect(componentInstance.stackFooter).toBeTruthy();
});
...
it("should set stackFooter to true when media$ emits 'sm' as mqAlias", () => {
   mockMediaSubject.next({mqAlias: 'sm'});

   expect(componentInstance.stackFooter).toBeTruthy();
});

Wow, it was difficult to type it into that editor. If i missed something and it won't work add comment with my name so i will see it. Hope that helps.

Upvotes: 1

Related Questions