You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 8中@Output属性的Jasmine单元测试配置及问题求助

Fixing "Cannot read properties of undefined (reading 'level')" in your Angular Jasmine Tests

Hey there! I see you're diving into Angular unit testing for the first time—great job getting started! The "position of undefined" error you're hitting is because your checkEmployeePosition input property isn't being initialized in your tests, so when clickToCheck() runs, it tries to access this.checkEmployeePosition.level on an undefined value. Let's fix this and get your tests working properly.

First, Fix the Component Syntax

Your component class has a small syntax error—implements { is incomplete. If you don't need to implement any interfaces, you can just remove that part:

export class testComponent { // Removed the incomplete "implements {"
  @Output() passVal = new EventEmitter();
  @Input() checkEmployeePosition: any;

  clickToCheck() {
    const testData = { position: this.checkEmployeePosition.level };
    this.passVal.emit(testData);
  }
}

Next, Fix the Test Issues

Let's walk through the changes needed in your testComponent.spec.ts:

  1. Initialize the Input Property
    In your beforeEach block (or individual test cases), set a value for checkEmployeePosition so it's not undefined:

    beforeEach(() => {
      fixture = TestBed.createComponent(testComponent);
      component = fixture.componentInstance;
      // Add this line to initialize the input
      component.checkEmployeePosition = { level: "senior" }; // Or any value you want to test
      de = fixture.debugElement;
      btn = de.query(By.css("button"));
      fixture.detectChanges(); // Trigger change detection to apply the input
    });
    
  2. Fix Invalid Test Code

    • Your second test calls component.emitContinue()—this method doesn't exist in your component! It should be component.clickToCheck().
    • All your tests expect passVal.emit to be called with 1, but your component emits an object like { position: "senior" } (matching the level value you set). Update your expectations to match the actual emitted data structure.

Here's the Full Corrected Spec File

import { DebugElement, ElementRef } from "@angular/core";
import { TestBed, ComponentFixture } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { testComponent } from "./testComponent.component";

fdescribe("testComponent", () => {
  let fixture: ComponentFixture<testComponent>;
  let component: testComponent;
  let de: DebugElement;
  let btn: ElementRef;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [testComponent],
    });
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(testComponent);
    component = fixture.componentInstance;
    // Initialize the input property to avoid undefined errors
    component.checkEmployeePosition = { level: "senior" };
    de = fixture.debugElement;
    btn = de.query(By.css("button"));
    fixture.detectChanges(); // Apply the input value to the component
  });

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

  describe("passVal output", () => {
    it("should emit the correct object when the button is clicked", () => {
      spyOn(component.passVal, "emit");
      btn.nativeElement.click();
      // Expect the emitted object to match the structure from clickToCheck()
      expect(component.passVal.emit).toHaveBeenCalledWith({ position: "senior" });
    });

    it("should emit the correct object when clickToCheck() is called directly", () => {
      spyOn(component.passVal, "emit");
      component.clickToCheck(); // Fixed the method name here
      expect(component.passVal.emit).toHaveBeenCalledWith({ position: "senior" });
    });

    it("should emit the correct object when button is clicked (using subscribe)", () => {
      let emittedData: any;
      component.passVal.subscribe(data => {
        emittedData = data;
      });
      btn.nativeElement.click();
      expect(emittedData).toEqual({ position: "senior" });
    });
  });
});

Key Takeaways

  • Always initialize @Input properties in your tests if your component uses their properties (like level here).
  • Make sure your test expectations match the actual data your component produces—your component emits an object, not a number!
  • Double-check method names in tests to ensure they match what's in your component.

内容的提问来源于stack exchange,提问作者Mr. Learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:32:56