I am relatively new to Angular Material unit testing and also to Service unit testing. I created a service for my application with which I can call a Material SnackBar open function and passing a message parameter through. It's working really fine in every component when it needed but the unit testing for it is something... terrible to me.
import { Injectable } from '@angular/core';
import { MatSnackBar, MatSnackBarRef, MatSnackBarConfig } from '@angular/material/snack-bar';
@Injectable({
providedIn: 'root',
})
export class NotificationService {
private snackBarConfig: MatSnackBarConfig;
private snackBarRef: MatSnackBarRef<any>;
private snackBarAutoHide = '5000';
constructor(private sb: MatSnackBar) {}
openSnackBar(message) {
this.snackBarConfig = new MatSnackBarConfig();
this.snackBarConfig.duration = parseInt(this.snackBarAutoHide, 0);
this.sb.open(message, 'Dismiss', this.snackBarConfig);
}
}
And the so-called test specification file is this:
import { Overlay } from '@angular/cdk/overlay';
import { TestBed } from '@angular/core/testing';
import { MatSnackBar } from '@angular/material/snack-bar';
import { createServiceFactory, SpectatorService } from '@ngneat/spectator';
import { NotificationService } from './notification-service';
describe('NotificationService testing:', () => {
let spectator: SpectatorService<NotificationService>;
const createService = createServiceFactory({
service: NotificationService,
providers: [MatSnackBar, Overlay],
entryComponents: [],
mocks: [NotificationService],
});
beforeEach(() => (spectator = createService()));
it('should openSnackBar() be known as function', () => {
expect(typeof spectator.service.openSnackBar).toEqual('function');
});
it('should be created', () => {
const dateService = spectator.inject(NotificationService);
spyOn(spectator.service, 'openSnackBar');
dateService.openSnackBar('Test');
expect(spectator.service.openSnackBar).toHaveBeenCalledWith('Test');
});
});
My question would be the followings:
- Why my karma coverage says the openSnackBar(message) method is not tested? I mean at least I testing if it is a function or not.
- How can I actually test a service like this on its own?
Thank you in advance.
Okay I solved it with little help from a friend. first problem is in my constructor I define a private, and not a public version of SnackBar (
private sb: MatSnackBar
->public sb: MatSnackBar
). Secondly I modified the test file a little bit and now it looks like this and working fine:Hope it helps if anybody is struggling with the same problem in the future. Also I am sure, there is a better, nicer way to do this but right now it's working and giving 100% coverage, which counts. But will warmly welcome modification suggestions in the future to this.