Reputation: 73
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
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:
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