The setup is Ionic Framework with Angular, and using Spectator to test. Here I want to test the different stages of working with the modal controller.
Setup of the tests
This is the setup of the test file
let spectator: Spectator<ChildSettingsViewComponent>;
let sut: ChildSettingsViewComponent;
const modalSpy = jasmine.createSpyObj('Modal', ['present', 'onDidDismiss']);
const createComponent = createComponentFactory({
component: ChildSettingsViewComponent,
providers: [
mockProvider(ModalController, {
create: () => modalSpy,
}),
],
});
beforeEach(() => {
spectator = createComponent();
sut = spectator.component;
});
Using the modal in the component
The following code is an example of using the ModalController in the component
public async openModal(): Promise<void> {
const modal = await this.modalController.create({
component: MyModalComponent,
});
modal.onDidDismiss().then((data) => {
if (data.data !== undefined) {
doSomething();
}
});
modal.present();
}
The tests
The following tests allows for testing through the method above.
it('Opens a MyModalComponent', fakeAsync(() => {
const modalController = spectator.inject(ModalController);
spyOn(modalController, 'create').and.callThrough();
sut.openModal();
spectator.tick();
expect(modalController.create).toHaveBeenCalledWith({
component: MyModalComponent,
});
}));
it('Presents modal', fakeAsync(() => {
sut.openModal();
spectator.tick();
expect(modalSpy.present).toHaveBeenCalled();
}));
it('Calls DoSomething when data is returned', fakeAsync(() => {
modalSpy.onDidDismiss.and.returnValue(
Promise.resolve({
data: {
firstName: 'Anna',
lastName: 'Andersson',
},
})
);
spyOn(sut, 'doSomething');
sut.openModal();
spectator.tick();
expect(sut.doSomething).toHaveBeenCalledOnce();
}));
it('Does not call doSomething when no data returned from modal', fakeAsync(() => {
modalSpy.onDidDismiss.and.returnValue(
Promise.resolve({ data: undefined })
);
spyOn(sut, 'doSomething');
sut.openModal();
spectator.tick();
expect(sut.doSomething).not.toHaveBeenCalled();
}));
});
And with that all code in the method in the component have been tested.