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

Kno*_*dge 6 testing debugging unit-testing karma-jasmine angular

我正在开发一个 Angular 应用程序,并在单元测试中使用 Jasmine 和 Karma。在我的组件规格之一中,我开始收到错误:Uncaught RangeError: Maximum call stack size exceeded

\n\n

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

\n\n
\n\n

有问题的组件 ( ) 的代码...component.spec.ts由下式给出:

\n\n
import {\n  ComponentFixture,\n  TestBed,\n  fakeAsync,\n  tick\n} from "@angular/core/testing";\nimport "hammerjs";\n\nimport { RegisterStudentComponent } from "./register-student.component";\n\nimport { MaterialModule } from "../../modules/material/material.module";\nimport { RouterTestingModule } from "@angular/router/testing";\nimport { ReactiveFormsModule } from "@angular/forms";\nimport { UserService } from "src/app/core/user.service";\nimport { userServiceStub } from "src/testing/user-service-stub";\nimport { LoadingComponent } from "src/app/loading/loading.component";\nimport { Location } from "@angular/common";\nimport { Routes } from "@angular/router";\n\nconst routes: Routes = [\n  {\n    path: "sch\xc3\xbcler",\n    component: RegisterStudentComponent\n  }\n];\n\ndescribe("RegisterStudentComponent", () => {\n  let component: RegisterStudentComponent;\n  let fixture: ComponentFixture<RegisterStudentComponent>;\n  let registerStudent: HTMLElement;\n  let location: Location;\n\n  beforeEach(() => {\n    TestBed.configureTestingModule({\n      declarations: [RegisterStudentComponent, LoadingComponent],\n      imports: [\n        MaterialModule,\n        RouterTestingModule.withRoutes(routes),\n        ReactiveFormsModule\n      ],\n      providers: [{ provide: UserService, useValue: userServiceStub }]\n    }).compileComponents();\n  });\n\n  beforeEach(() => {\n    fixture = TestBed.createComponent(RegisterStudentComponent);\n    component = fixture.componentInstance;\n    registerStudent = fixture.nativeElement;\n\n    fixture.detectChanges();\n\n    location = TestBed.get(Location);\n  });\n\n  const setupValidForm = () => {\n    component.subjects = ["Physics"];\n    component.selectedSubjects = ["Physics"];\n    component.form.setValue({\n      agb: true,\n      email: "test@test.de",\n      hourlyRate: 5,\n      password: "test",\n      name: "test"\n    });\n  };\n\n  it("should create", () => {\n    expect(component).toBeTruthy();\n  });\n\n  it("should add subject if click on subject button", () => {\n    component.subjects = ["Physics"];\n    fixture.detectChanges();\n\n    let physicsButton = registerStudent.querySelector("div[class=subjects]")\n      .children[0];\n    physicsButton.dispatchEvent(new Event("click"));\n\n    expect(component.selectedSubjects.includes("Physics")).toBeTruthy();\n  });\n\n  it("should remove subject if selected subject is clicked", () => {\n    component.subjects = ["Physics"];\n    component.selectedSubjects = ["Physics"];\n    fixture.detectChanges();\n\n    let physicsButton = registerStudent.querySelector("div[class=subjects]")\n      .children[0];\n    physicsButton.dispatchEvent(new Event("click"));\n\n    expect(component.selectedSubjects).toEqual([]);\n  });\n\n  it("should be initialized invalid", () => {\n    expect(component.isValid()).not.toBeTruthy();\n  });\n\n  it("should be valid if filled out", () => {\n    setupValidForm();\n    fixture.detectChanges();\n\n    expect(component.isValid()).toBeTruthy();\n  });\n\n  it("should be invalid if no subject is selected", () => {\n    setupValidForm();\n    component.selectedSubjects = [];\n    fixture.detectChanges();\n    expect(component.isValid()).not.toBeTruthy();\n  });\n\n  it("should not be valid if email is not valid", () => {\n    setupValidForm();\n    component.form.setValue({ ...component.form.value, email: "test" });\n    fixture.detectChanges();\n    expect(component.isValid()).not.toBeTruthy();\n  });\n\n  it("should not be valid if email is empty", () => {\n    setupValidForm();\n    component.form.setValue({ ...component.form.value, email: "" });\n    fixture.detectChanges();\n    expect(component.isValid()).not.toBeTruthy();\n  });\n\n  it("should not be valid if password is empty", () => {\n    setupValidForm();\n    component.form.setValue({ ...component.form.value, password: "" });\n    fixture.detectChanges();\n    expect(component.isValid()).not.toBeTruthy();\n  });\n\n  it("should not be valid if agbs are not checked", () => {\n    setupValidForm();\n    component.form.setValue({ ...component.form.value, agb: false });\n    fixture.detectChanges();\n    expect(component.isValid()).not.toBeTruthy();\n  });\n\n  // it("should load until user registration is complete", fakeAsync(() => {\n  //   setupValidForm();\n  //   let submitButton = registerStudent.querySelector<HTMLButtonElement>(\n  //     "main > button"\n  //   );\n  //   submitButton.click();\n  //   tick();\n  //   expect(component.isLoading).toBeTruthy();\n  // }));\n\n  it("should redirect to student profile after click on registration button", fakeAsync(() => {\n    setupValidForm();\n    let submitButton = registerStudent.querySelector<HTMLButtonElement>(\n      "main > button"\n    );\n    submitButton.click();\n    tick();\n    expect(location.path()).toBe("/sch%C3%BCler");\n  }));\n});\n\n
Run Code Online (Sandbox Code Playgroud)\n

Sar*_*iel 1

当您使用一个调用另一个函数的函数,并且另一个函数调用另一个函数等等时,可能会发生这种情况。

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

    fit('example', function () {
    // 
});
Run Code Online (Sandbox Code Playgroud)

忽略特定测试:使用xit

        xit('example', function () {
        // 
    });
Run Code Online (Sandbox Code Playgroud)

比它会忽略特定的测试。

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