Khadija Daruwala
Khadija Daruwala

Reputation: 1205

Unit tests for alert controller in ionic

I am learning to write unit tests in ionic and am unable to write a test for AlertController. Below attached is the code

Terms.page.ts file

 export class TermsPage {
      constructor(private router: Router, private alertController: AlertController) {}
    
      onAgreeClick() {
        this.router.navigate(['/register']);
      }
    
      onDeclineClick() {
        this.presentAlertConfirm();
      }
    
      async presentAlertConfirm() {
        const alert = await this.alertController.create({
          message: 'Please agree to our terms and conditions to be able to use this application!',
          buttons: [
            {
              text: 'Agree',
              cssClass: 'primary',
              handler: () => {
                this.onAgreeClick();
              },
            },
            {
              text: 'Maybe later',
              role: 'cancel',
              cssClass: 'secondry',
            },
          ],
        });
        await alert.present();
      }
    }

Terms.spec.ts

import { DebugElement } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Router, RouterModule } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { EmptyTestComponent } from '@test-utils';

import { TermsPage } from './terms.page';

fdescribe('TermsConditionsComponent', () => {
  let component: TermsPage;
  let fixture: ComponentFixture<TermsPage>;
  let de: DebugElement;
  let router: Router;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [TermsPage],
      imports: [
        RouterModule.forRoot([]),
        RouterTestingModule.withRoutes([{ path: '**', component: EmptyTestComponent }]),
      ],
    }).compileComponents();

    fixture = TestBed.createComponent(TermsPage);
    component = fixture.componentInstance;
    de = fixture.debugElement;

    router = TestBed.inject(Router);
    fixture.detectChanges();
  }));

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should be able to agree and go to registration on click', async () => {
    const agreeButton = de.query(By.css('#button-agree')).nativeElement as HTMLIonButtonElement;
    agreeButton.click();
    await fixture.whenStable();
    expect(router.url).toBe('/register');
  });

  it('should be able to trigger popup on click of disagree click', async () => {
    const disagreeButton = de.query(By.css('#button-disagree')).nativeElement as HTMLIonButtonElement;
    disagreeButton.click();
    await fixture.whenStable();
    expect(component.presentAlertConfirm).toBeTruthy();
  });
});

I need to hit the 100% coverage enter image description here

Would really appreciate it if someone could help me write test case to cover the alert button actions and present. Thanks in advance

Upvotes: 1

Views: 1991

Answers (1)

North Halcyon
North Halcyon

Reputation: 127

Looks like you need to split your test into two:

  • test #1 for alertcontroller.create usage - to has been called with proper arguments
  • and test #2 for button handlers

First can be easely emulated with standard jasmine calls like .toHaveBeenCalledWith(...):

const alertControllerStub = jasmine.createSpyObj('AlertController', ['create']);
...
expect(alertControllerStub.create).toHaveBeenCalledWith(options);

And the second one, you need to fire "ok"/"cancel" manually and catch the method executed for both cases

const ({buttons}) = alertControllerStub.create.calls.first().args[0];
buttons[0].handler();
expect(smth_should_called_in_handler).toHaveBeenCalled();

Upvotes: 3

Related Questions