dimanche 24 novembre 2019

Karma: How to debug a RangeError: Maximum call stack size exceeded?

I am developing an Angular App and use Jasmine with Karma in my Unit testing. In one of my component specs I started to get the error: Uncaught RangeError: Maximum call stack size exceeded.

I am having a hard time finding/ understanding the cause of this stack overflow and would be happy for a structured way to debug this error.


The code of the problematic component (...component.spec.ts) is given by:

import {
  ComponentFixture,
  TestBed,
  fakeAsync,
  tick
} from "@angular/core/testing";
import "hammerjs";

import { RegisterStudentComponent } from "./register-student.component";

import { MaterialModule } from "../../modules/material/material.module";
import { RouterTestingModule } from "@angular/router/testing";
import { ReactiveFormsModule } from "@angular/forms";
import { UserService } from "src/app/core/user.service";
import { userServiceStub } from "src/testing/user-service-stub";
import { LoadingComponent } from "src/app/loading/loading.component";
import { Location } from "@angular/common";
import { Routes } from "@angular/router";

const routes: Routes = [
  {
    path: "schüler",
    component: RegisterStudentComponent
  }
];

describe("RegisterStudentComponent", () => {
  let component: RegisterStudentComponent;
  let fixture: ComponentFixture<RegisterStudentComponent>;
  let registerStudent: HTMLElement;
  let location: Location;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [RegisterStudentComponent, LoadingComponent],
      imports: [
        MaterialModule,
        RouterTestingModule.withRoutes(routes),
        ReactiveFormsModule
      ],
      providers: [{ provide: UserService, useValue: userServiceStub }]
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(RegisterStudentComponent);
    component = fixture.componentInstance;
    registerStudent = fixture.nativeElement;

    fixture.detectChanges();

    location = TestBed.get(Location);
  });

  const setupValidForm = () => {
    component.subjects = ["Physics"];
    component.selectedSubjects = ["Physics"];
    component.form.setValue({
      agb: true,
      email: "test@test.de",
      hourlyRate: 5,
      password: "test",
      name: "test"
    });
  };

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

  it("should add subject if click on subject button", () => {
    component.subjects = ["Physics"];
    fixture.detectChanges();

    let physicsButton = registerStudent.querySelector("div[class=subjects]")
      .children[0];
    physicsButton.dispatchEvent(new Event("click"));

    expect(component.selectedSubjects.includes("Physics")).toBeTruthy();
  });

  it("should remove subject if selected subject is clicked", () => {
    component.subjects = ["Physics"];
    component.selectedSubjects = ["Physics"];
    fixture.detectChanges();

    let physicsButton = registerStudent.querySelector("div[class=subjects]")
      .children[0];
    physicsButton.dispatchEvent(new Event("click"));

    expect(component.selectedSubjects).toEqual([]);
  });

  it("should be initialized invalid", () => {
    expect(component.isValid()).not.toBeTruthy();
  });

  it("should be valid if filled out", () => {
    setupValidForm();
    fixture.detectChanges();

    expect(component.isValid()).toBeTruthy();
  });

  it("should be invalid if no subject is selected", () => {
    setupValidForm();
    component.selectedSubjects = [];
    fixture.detectChanges();
    expect(component.isValid()).not.toBeTruthy();
  });

  it("should not be valid if email is not valid", () => {
    setupValidForm();
    component.form.setValue({ ...component.form.value, email: "test" });
    fixture.detectChanges();
    expect(component.isValid()).not.toBeTruthy();
  });

  it("should not be valid if email is empty", () => {
    setupValidForm();
    component.form.setValue({ ...component.form.value, email: "" });
    fixture.detectChanges();
    expect(component.isValid()).not.toBeTruthy();
  });

  it("should not be valid if password is empty", () => {
    setupValidForm();
    component.form.setValue({ ...component.form.value, password: "" });
    fixture.detectChanges();
    expect(component.isValid()).not.toBeTruthy();
  });

  it("should not be valid if agbs are not checked", () => {
    setupValidForm();
    component.form.setValue({ ...component.form.value, agb: false });
    fixture.detectChanges();
    expect(component.isValid()).not.toBeTruthy();
  });

  // it("should load until user registration is complete", fakeAsync(() => {
  //   setupValidForm();
  //   let submitButton = registerStudent.querySelector<HTMLButtonElement>(
  //     "main > button"
  //   );
  //   submitButton.click();
  //   tick();
  //   expect(component.isLoading).toBeTruthy();
  // }));

  it("should redirect to student profile after click on registration button", fakeAsync(() => {
    setupValidForm();
    let submitButton = registerStudent.querySelector<HTMLButtonElement>(
      "main > button"
    );
    submitButton.click();
    tick();
    expect(location.path()).toBe("/sch%C3%BCler");
  }));
});

Aucun commentaire:

Enregistrer un commentaire