开发者问题收集

业力:如何调试 RangeError:超出最大调用堆栈大小?

2019-11-24
8505

我正在开发一个 Angular 应用,并在单元测试中使用 Jasmine 和 Karma。在我的某个组件规范中,我开始收到错误: Uncaught RangeError:超出最大调用堆栈大小

我很难找到/理解此堆栈溢出的原因,并希望有一种结构化的方法来调试此错误。


有问题的组件 ( ...component.spec.ts ) 的代码如下:

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: "[email protected]",
      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");
  }));
});

2个回答

我遇到了类似的问题,然后我做了以下操作: 只需停止测试服务器并再次运行它 。 这解决了我的问题。

Priya Shelke
2022-08-20

当您使用一个函数调用另一个函数,而另一个函数又调用另一个函数等等时,就会发生这种情况。

我会尝试通过每次运行一组测试来隔离问题。 运行单个测试: 使用 fit 而不是 it

    fit('example', function () {
    // 
});

忽略特定测试: 使用 xit

        xit('example', function () {
        // 
    });

然后它将忽略特定测试。

希望它能帮助您找到问题所在。

Sariel
2019-11-24