Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error 'Cannot read property 'triggerEventHandler' of null' in Karma unit testing

I am trying to test if a closeModal function in a Modal component is working when clicking a "close button" on the modal, however this test shows my button element as null. I am getting the error "Cannot read property 'triggerEventHandler' of null." How can I resolve this?

modal.component.ts

import { AppComponent } from "./../app.component";
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { ModalComponent } from "./modal.component";
import { By } from '@angular/platform-browser';

describe("ModalComponent", () => {
  let component: ModalComponent;
  let fixture: ComponentFixture<ModalComponent>;

  beforeEach(
    async(() => {
      TestBed.configureTestingModule({
        declarations: [ModalComponent, AppComponent]
      }).compileComponents();
    })
  );

  beforeEach(() => {
    fixture = TestBed.createComponent(ModalComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

  it("should test closeModal method on close button", () => {
    spyOn(component, "closeModal")
    let el = fixture.debugElement.query(By.css('#close'))
    el.triggerEventHandler('click', null)

    fixture.detectChanges()

    fixture.whenStable().then(() => {
      expect(component.closeModal).toHaveBeenCalled();
    });
  });
});

modal.component.html

<div class="ds-c-dialog-wrap"[ngClass]="hideModal ? 'hide' : 'show'">
  <div>
    <header role="banner">
      <h1 id="dialog-title">{{modalTitle}}</h1>
      <button
      id="button"
      (click)="closeModal()"
      *ngIf="enableClose">Close</button>
    </header>
    <main>
      <p class="ds-text">
        {{modalBody}}
    </main>
    <aside role="complementary">
      <button>Dialog action</button>
      <button *ngIf="enableCancel" (click)="closeModal()">Cancel</button>
    </aside>
  </div>
</div>
like image 452
FakeEmpire Avatar asked Jan 24 '18 16:01

FakeEmpire


People also ask

What is ComponentFixture in jasmine?

The ComponentFixture is a test harness for interacting with the created component and its corresponding element. Access the component instance through the fixture and confirm it exists with a Jasmine expectation: content_copy const component = fixture. componentInstance; expect(component).

What is TestBed in Angular testing?

TestBed is the primary api for writing unit tests for Angular applications and libraries.

What is fixture DebugElement?

DebugElement is an Angular class that contains all kinds of references and methods relevant to investigate an element as well as component fixture.debugElement.query(By.css('#shan'))

What is fixture detectChanges?

fixture. detectChanges() tells Angular to run change-detection. Finally! Every time it is called, it updates data bindings like ng-if, and re-renders the component based on the updated data. Calling this function will cause ngOnInit to run only the first time it is called.


1 Answers

I believe your problem is with *ngIf="enableClose">Close</button>. You will need to set enableClose to true before you try to to access it. Try something like this:

it("should test closeModal method on close button", () => {

    spyOn(component, "closeModal")

    component.enableClose = true; // set your variable to true
    fixture.detectChanges(); // update everything to reflect the true state

    let el = fixture.debugElement.query(By.css('#close'))
    el.triggerEventHandler('click', null)

    fixture.detectChanges()

    fixture.whenStable().then(() => {
        expect(component.closeModal).toHaveBeenCalled();
    });
});

Also, I noticed in your html the close button has an id of button, but in your test you are looking for #close, is that correct which means your button id should be close?

like image 109
Mike Avatar answered Oct 17 '22 05:10

Mike