Angular Jest测试报错:Cannot read properties of undefined (reading 'ɵcmp')求助
问题描述
我有一个父组件,其包含的子组件在模板中使用了该父组件。最初项目构建失败,使用forwardRef后构建成功,但现在父、子组件及其他依赖父组件的组件的Jest单元测试均报错:Cannot read properties of undefined (reading 'ɵcmp'),求解决方法。
相关代码
parent.component.ts
import {Component} from '@angular/core'; import {ChildComponent} from "./child/child.component"; @Component({ selector: 'parent', standalone: true, imports: [ChildComponent], templateUrl: './parent.component.html', styleUrl: './parent.component.css' }) export class ParentComponent { }
parent.component.html
Parent <child [hideParent]="false"/>
parent.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ParentComponent } from './parent.component'; describe('ParentComponent', () => { let component: ParentComponent; let fixture: ComponentFixture<ParentComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ParentComponent] }) .compileComponents(); fixture = TestBed.createComponent(ParentComponent); component = fixture.componentInstance; }); it('should create', () => { expect(component).toBeTruthy(); }); });
child.component.ts
import {Component, forwardRef, input} from '@angular/core'; import {ParentComponent} from "../parent.component"; @Component({ selector: 'child', standalone: true, imports: [forwardRef(() => ParentComponent)], templateUrl: './child.component.html', styleUrl: './child.component.css' }) export class ChildComponent { hideParent = input(false); }
child.component.html
Child @if (hideParent()) { <parent /> }
child.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ChildComponent } from './child.component'; import {ParentComponent} from "../parent.component"; describe('ChildComponent', () => { let component: ChildComponent; let fixture: ComponentFixture<ChildComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ChildComponent, ParentComponent] }) .compileComponents(); fixture = TestBed.createComponent(ChildComponent); component = fixture.componentInstance; }); it('should create', () => { expect(component).toBeTruthy(); }); }); // 子组件测试失败
解决方法
1. 测试模块中用forwardRef包裹循环依赖组件
在子组件测试中,直接同时导入循环依赖的两个组件会导致Jest无法正确解析组件定义,用forwardRef包裹父组件导入即可解决:
import { ComponentFixture, TestBed, forwardRef } from '@angular/core/testing'; import { ChildComponent } from './child.component'; import { ParentComponent } from "../parent.component"; describe('ChildComponent', () => { let component: ChildComponent; let fixture: ComponentFixture<ChildComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ ChildComponent, forwardRef(() => ParentComponent) ] }).compileComponents(); fixture = TestBed.createComponent(ChildComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); });
2. 模拟循环依赖组件(推荐)
如果测试不需要依赖真实组件的完整功能,模拟一个极简版本的组件来替代,彻底打破循环依赖:
子组件测试模拟父组件
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ChildComponent } from './child.component'; import { Component, input } from '@angular/core'; // 模拟父组件 @Component({ selector: 'parent', template: '<div>Mock Parent</div>' }) class MockParentComponent {} describe('ChildComponent', () => { let component: ChildComponent; let fixture: ComponentFixture<ChildComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ChildComponent], declarations: [MockParentComponent] }).compileComponents(); fixture = TestBed.createComponent(ChildComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); it('should render mock parent when hideParent is true', () => { component.hideParent.set(true); fixture.detectChanges(); const parentElement = fixture.nativeElement.querySelector('parent'); expect(parentElement).toBeTruthy(); }); });
父组件测试模拟子组件
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ParentComponent } from './parent.component'; import { Component, input } from '@angular/core'; // 模拟子组件 @Component({ selector: 'child', template: '<div>Mock Child</div>' }) class MockChildComponent { hideParent = input(false); } describe('ParentComponent', () => { let component: ParentComponent; let fixture: ComponentFixture<ParentComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [ParentComponent], declarations: [MockChildComponent] }).compileComponents(); fixture = TestBed.createComponent(ParentComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); });
3. 确保版本兼容
确认Angular 17与Jest及@angular-builders/jest版本匹配,避免因版本不兼容导致的组件编译解析问题。
内容的提问来源于stack exchange,提问作者Alex Alex
相关产品推荐
相关产品推荐

