Unit Testing PrimeNG Confirm Dialog | Karma | Jasmine


How to unit test PrimeNG ConfirmDialog ConfirmationService.

{% include youtube_embed.html id=“bUkDmZYRZlM” %}

Let’s say you are using the PrimeNG confirmDialog. Here is how your app.component.html looks:

<p-confirmDialog  header="Confirmation"  icon="pi pi-exclamation-triangle"></p-confirmDialog>
<button  (click)="confirm()"  pButton  icon="pi pi-check"  label="Confirm"></button>

Here is the app.component.ts file.

import { Component, OnInit } from '@angular/core';
import { ConfirmationService } from 'primeng/api';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [ConfirmationService]
})
export class AppComponent implements OnInit {
  
  public confirmSuccess: any;
  public confirmReject: any;

  constructor(private confirmationService: ConfirmationService) { }

  ngOnInit() {
    
  }

  confirm() {
    this.confirmationService.confirm({
      message: 'Are you sure that you want to perform this action?',
      accept: () => {
        this.confirmSuccess = true;
        this.confirmReject = false;
      },
      reject: () => {
        this.confirmReject = true;
        this.confirmSuccess = false;
      }
    });
  }

}

Let’s write unit test for testing the confirm dialog. One scenario to write unit test is when the user clicks on accept and another when the user clicks on reject.

Unit Testing Accept

For unit testing accept scenario, you need to get reference to the accept button an simulate a click. Once clicked you check if the accept callback function has been called or not. Here is the test case looks:

  it('should call confirm with accept button click', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const component = fixture.componentInstance;
    let confirmdialog : ConfirmDialog;
    confirmdialog = fixture.debugElement.query(By.css('p-confirmdialog')).componentInstance;
    let accept = spyOn(confirmdialog,"accept").and.callThrough();
    component.confirm();
    fixture.detectChanges();
    let acceptBtn = fixture.debugElement.nativeElement.querySelector('.p-confirm-dialog-accept');
    acceptBtn.click();
    expect(accept).toHaveBeenCalled();
    expect(component.confirmSuccess).toEqual(true);
    expect(component.confirmReject).toEqual(false);
  })

Unit Testing Reject

Similar to the above unit test case, you need to simulate no or reject button click and verify if the reject callback gets called. Here is how the unit test case looks:

  it('should call confirm with no button click', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const component = fixture.componentInstance;
    let confirmdialog : ConfirmDialog;
    confirmdialog = fixture.debugElement.query(By.css('p-confirmdialog')).componentInstance;
    let reject = spyOn(confirmdialog,"reject").and.callThrough();
    component.confirm();
    fixture.detectChanges();
    let cancelBtn = fixture.debugElement.nativeElement.querySelector('.p-confirm-dialog-reject');
    cancelBtn.click();
    expect(reject).toHaveBeenCalled();
    expect(component.confirmSuccess).toEqual(false);
    expect(component.confirmReject).toEqual(true);
  })

Complete Unit Test

Here is the complete app.component.spec.ts file looks:

import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { HttpClientTestingModule } from '@angular/common/http/testing'
import { By } from '@angular/platform-browser';
import {ConfirmDialog, ConfirmDialogModule} from 'primeng/confirmdialog';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DatePipe } from '@angular/common';


describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        HttpClientTestingModule,
        ConfirmDialogModule,
        BrowserAnimationsModule
      ],
      declarations: [
        AppComponent
      ],
      providers:[DatePipe]
    }).compileComponents();
  });

  it('should call confirm with accept button click', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const component = fixture.componentInstance;
    let confirmdialog : ConfirmDialog;
    confirmdialog = fixture.debugElement.query(By.css('p-confirmdialog')).componentInstance;
    let accept = spyOn(confirmdialog,"accept").and.callThrough();
    component.confirm();
    fixture.detectChanges();
    let acceptBtn = fixture.debugElement.nativeElement.querySelector('.p-confirm-dialog-accept');
    acceptBtn.click();
    expect(accept).toHaveBeenCalled();
    expect(component.confirmSuccess).toEqual(true);
    expect(component.confirmReject).toEqual(false);
  })

  it('should call confirm with no button click', () => {
    const fixture = TestBed.createComponent(AppComponent);
    const component = fixture.componentInstance;
    let confirmdialog : ConfirmDialog;
    confirmdialog = fixture.debugElement.query(By.css('p-confirmdialog')).componentInstance;
    let reject = spyOn(confirmdialog,"reject").and.callThrough();
    component.confirm();
    fixture.detectChanges();
    let cancelBtn = fixture.debugElement.nativeElement.querySelector('.p-confirm-dialog-reject');
    cancelBtn.click();
    expect(reject).toHaveBeenCalled();
    expect(component.confirmSuccess).toEqual(false);
    expect(component.confirmReject).toEqual(true);
  })

});