I am making a simple snackbar for which code as follows,
app.component.ts:
ngOnInit(){
this.dataService.valueChanges.pipe(
filter((data) =>data=== true),
switchMap(() => {
const snackBarRef = this.matSnackBar.open(
'A new value updated',
'OK',
{
duration: 3000
}
);
return snackBarRef.onAction();
})
)
.subscribe(() => {
this.window.location.reload();
});
}
app.component.spec.ts (Including mock data for service)
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let matSnackBarSpy: jasmine.SpyObj<MatSnackBar>;
let a = "";
let b = "";
let c = "";
const mockDataService = {
valueChanges: of(true)
};
beforeEach(async(() => {
TestBed.configureTestingModule({
a = "Test";
b = "X";
c = "suc";
matSnackBarSpy = TestBed.get<MatSnackBar>(MatSnackBar);
})
}))
describe('#ngOnInit()', () => {
it('should call MatSnackBar.open()', async(done: DoneFn) => {
const error = new HttpErrorResponse({ error: 'Some error' });
component.ngOnInit();
expect(mockDataService.valueChanges).toBeTruthy();
expect(matSnackBarSpy.open(a,b,c)).toBeTruthy();
done();
});
});
})
data.service.ts
import { Observable } from 'rxjs';
export class DataService {
valueChanges: Observable<boolean>;
}
Explanation:
I am having a service which has the property valueChanges
with type as Observable<boolean>
.
In component.ts
, I am getting the value change as like mentioned above and end result I receive is boolean value true
and also snackbar gets opened and everything is working fine.
Now I am into implementation of test cases for the above like in compoenent.spec.ts
,
expect(mockDataService.valueChanges).toBeTruthy();
expect(matSnackBarSpy.open(a,b,c)).toBeTruthy();
This results in success case but I am forever receiving this below output in chrome.
Requirement: Need to cover all the tests that currently shows warning/indication of not covered in the above image..
Above test cases are running but test coverage shows still function not covered and also statement not covered warning when we open index.html
of the component.
So, you basically should test whether matSnackBar
methods are called properly or not. Testing behavior of matSnackBar
is not a unit testing.
Try
class MatSnackBarStub{
open(){
return {
onAction: () => of({})
};
}
}
in component.spec
file
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SomeComponent],
providers: [{provide: MatSnackBar , useClass: MatSnackBarStub}]
}).compileComponents();
}));
it('should create', () => {
spyOn(component.matSnackBar,"open").and.callThrough();
component.ngOnInit();
expect(component.matSnackBar.open).toHaveBeenCalled();
// you can also use ".toHaveBeenCalledWith" with necessary params
});
I would suggest you to take a look at this collection of articles related to unit testing using jasmine and karma. There is one article on how to use stubs and spies. I hope this would help