Reputation: 1115
Angular Unit Test - Mocked Service is not being used
I'm pretty new to coding and I am trying to write my own app to learn Angular. As a good developer I am writing tests for my code but I am having a little issue.
I have created a wrapper service that uses the Angular Material Dialog, this is the method in my component that calls the wrapper service (here's some code)
this how I declare the service in my component
constructor(private modalDialogWrapperService: ModalDialogWrapperService) {}
this is method that calls the service.
public assignInstrument(instrument: any): void {
this.modalDialogWrapperService.openAssignmentWindow({
product: 'instrument',
type: instrument.type,
serial: instrument.serial,
id: instrument.id
});
}
Now all this works fine but I want to test the component that when assignInstrument is executed the modalDialogWrapperService.openAssignmentWindow is called. Here is my test file
describe('InstrumentsPageComponent', () => {
let component: InstrumentsPageComponent;
let fixture: ComponentFixture<InstrumentsPageComponent>;
let modalDialogWrapperServiceSpy: jasmine.SpyObj<ModalDialogWrapperService>;
beforeEach(async(() => {
const mockModalDialogWrapperService =
jasmine.createSpyObj('ModalDialogWrapperService', ['openAssignmentWindow']);
mockModalDialogWrapperService.openAssignmentWindow.and.returnValue(of({}));
TestBed.configureTestingModule({
imports: [MatTableModule, MatPaginatorModule, MatDialogModule, NoopAnimationsModule],
declarations: [InstrumentsPageComponent, ChangeAssignmentComponent],
providers: [{
provide: ModalDialogWrapperService,
useValue: mockModalDialogWrapperService}]
})
.overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [ChangeAssignmentComponent]}})
.compileComponents();
beforeEach(() => {
fixture = TestBed.createComponent(InstrumentsPageComponent);
modalDialogWrapperServiceSpy = TestBed.get(ModalDialogWrapperService);
component = fixture.componentInstance;
fixture.detectChanges();
});
describe('assignInstrument', () => {
it('should call the Modal Dialog Service', () => {
component.assignInstrument({});
expect(modalDialogWrapperServiceSpy.openAssignmentWindow).toHaveBeenCalledTimes(1);
});
});
Now this brings back the error "openAssignmentWindow to have been called once. It was called 0 times.". I've noticed that if I write console.log(this.modalDialogWrapperService);
in my component's ngOnInit(
) it looks as if the dalDialogWrapperService does not get replaced in the Jasmine stub. What am I doing wrong?
Upvotes: 1
Views: 2742
Reputation: 6183
Your approach might be a bit of an overkill if you just want to validate if the service method has been called. You could just set up a spy on the actual service instead of providing a mock service that does pretty much the same thing.
Here is how I would implement this test
In your first describe
block add your a service reference:
let modalDialogWrapperService: ModalDialogWrapperService;
Provide it as you normally would in a module, but in your beforeEach(async())
:
providers: [ModalDialogWrapperService]
In your beforeEach()
get the service via the TestBed
:
modalDialogWrapperService = TestBed.get(ModalDialogWrapperService);
And then your test would look like this:
describe('assignInstrument', () => {
it('should call the Modal Dialog Service', () => {
let spy = spyOn(modalDialogWrapperService, 'openAssignmentWindow').and.returnValue(of({}));
expect(spy).not.toHaveBeenCalled();
component.assignInstrument({});
expect(spy).toHaveBeenCalledTimes(1);
});
});
This requires less code and looks a bit cleaner in my opinion.
Stackblitz can be found here.
Upvotes: 0