Testing with Ionic ModalController in Angular using Spectator


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.


Leave a Reply

Your email address will not be published. Required fields are marked *