Reputation: 757
I'm doing unit testing in Angular 6, but I'm having trouble testing this IF
branch. I use it to observe how big the screen is, and so to decide how many columns I'll display. I'm struggling with how to test inside the subscribe that is in ngOnInit()
.
This
this.watcher = this.media.subscribe((change: MediaChange) =>....
code coverage show that it does not go into the if
and else
of these services. This was the best I could do. The Media Change service keeps looking at which screen size, to decide how many columns it would display in the table
ngOnInit() {
this.watcher = this.media.subscribe((change: MediaChange) => {
this.activeMediaQuery = change ? `'${change.mqAlias}' = (${change.mediaQuery})` : '';
this.changeMqAlias = change.mqAlias;
if (this.changeMqAlias == this.changeSize.XS) {
this.displayedColumns = ['job', 'name', 'totalValue'];
} else {
this.displayedColumns = ['internalId', 'DateOfPublication', 'alias', 'job', 'name', 'totalValue'];
}
return change.mqAlias;
});
}
it('should create', () => {
fixture.whenStable().then(() => {
expect(component).toBeTruthy();
});
});
it('should create which 3 columns in mat table', () => {
fixture.whenStable().then(() => {
component.changeMqAlias = 'xs';
expect(component).toBeTruthy();
});
});
});
Upvotes: 1
Views: 1462
Reputation: 6070
There are different ways you could approach this. The key to testing inside the subscribe is that you must mock the ObservableMedia
service such that it returns an observable. Then you can change the values of component.changeMqAlias
to different values and see that your 'if' resolves properly both ways.
I have set up a Stackblitz to show you one approach to testing the function as given. Here is the describe
from that Stackblitz:
describe('app testing', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
const mockFlex = of({ // create an Observable that returns a desired result
mqAlias: 'xs',
mediaQuery: 'test mQ'
});
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ MatTableModule /* Other imports needed */ ],
declarations: [ MyComponent ],
providers: [
{ provide: ObservableMedia, useValue: mockFlex }
]
}).compileComponents();
fixture = TestBed.createComponent(MyComponent);
component = fixture.debugElement.componentInstance;
}));
it('should create', () => {
expect(component).toBeTruthy();
});
it('should have 3 columns in mat table when changeMqAlias === "xs"', () => {
component.changeMqAlias = 'xs';
fixture.detectChanges();
expect(component.displayedColumns).toEqual(['job', 'name', 'totalValue']);
});
it('should have 6 columns in mat table when changeMqAlias !== "xs"', () => {
component.changeMqAlias = 'xl';
fixture.detectChanges();
expect(component.displayedColumns.length).toEqual(6);
});
});
Some notes about this:
MyComponent
.mockFlex
setup and also that it is substituted in the providers array to the TestBed for ObservableMedia
.fixture.detectChanges()
is not called until AFTER changeMqAlias
has been set. The reason for this is because fixture.detectChanges()
will call ngOnInit()
and you need to have this variable set ahead of time to control the path through your IF
statement. Details in the official documentation.Upvotes: 2