Angular测试:Mock组件未覆盖真实组件问题求助
Angular独立组件测试中Mock组件未生效的问题
问题描述
我正在为AskComponent编写单元测试,希望Mock内嵌的EditComponent,但运行测试时控制台输出"edit new",说明真实的EditComponent仍被实例化。只有将EditComponent的选择器改为'stt-edit2'时,EditStubComponent才会被注入。
测试脚本
import {ComponentFixture, TestBed} from '@angular/core/testing'; import {AskComponent} from './ask.component'; import {HttpClientTestingModule, HttpTestingController} from "@angular/common/http/testing"; import {HttpClient} from "@angular/common/http"; import {Component} from "@angular/core"; @Component({standalone: true, selector: 'stt-edit', template: ''}) class EditStubComponent { constructor() { console.log('edit stub new'); } } describe('AskComponent', () => { let httpClient: HttpClient; let httpTestingController: HttpTestingController; let askComponent: AskComponent; let fixture: ComponentFixture<AskComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ imports: [EditStubComponent, AskComponent, HttpClientTestingModule] }) .compileComponents(); httpClient = TestBed.inject(HttpClient); httpTestingController = TestBed.inject(HttpTestingController); fixture = TestBed.createComponent(AskComponent); askComponent = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(askComponent).toBeTruthy(); }); });
EditComponent代码
//import ... @Component({ selector: 'stt-edit', standalone: true, imports: [ ... ], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => EditComponent), multi: true } ], templateUrl: './edit.component.html', styleUrl: './edit.component.css' }) export class EditComponent implements ControlValueAccessor { constructor() { console.log('edit new'); } // ... }
问题原因
AskComponent作为独立组件,自身的imports数组中直接引入了真实的EditComponent。当你在TestBed的imports中同时导入AskComponent和EditStubComponent时,Angular会优先加载AskComponent依赖的真实EditComponent,导致Stub组件被忽略。
解决方案
需要通过TestBed.overrideComponent()方法显式替换AskComponent依赖的真实组件为Stub组件:
修改测试中的beforeEach代码:
beforeEach(async () => { await TestBed.configureTestingModule({ imports: [HttpClientTestingModule] }) // 覆盖AskComponent的依赖,替换真实组件为Stub .overrideComponent(AskComponent, { remove: { imports: [EditComponent] }, add: { imports: [EditStubComponent] } }) .compileComponents(); httpClient = TestBed.inject(HttpClient); httpTestingController = TestBed.inject(HttpTestingController); fixture = TestBed.createComponent(AskComponent); askComponent = fixture.componentInstance; fixture.detectChanges(); });
关键说明
- 不需要再将AskComponent和EditStubComponent直接加入TestBed的
imports数组 - 通过
overrideComponent可以精准修改目标组件的依赖配置,移除真实的EditComponent并添加Stub组件 - 这样Angular在实例化AskComponent时,会使用你定义的EditStubComponent而非真实组件
内容的提问来源于stack exchange,提问作者Galdor
相关产品推荐
相关产品推荐

