Angular7执行ng test单元测试报router-outlet需添加CUSTOM_ELEMENTS_SCHEMA错误
报错原因
你在PatientGroupComponent的单元测试文件中,错误将无关的AppComponent也声明到了TestBed配置中,还额外实例化了AppComponent。而AppComponent模板中使用了<router-outlet>标签,TestBed的当前配置无法识别该标签,因此触发报错。
另外你的TestBed配置存在多处冗余错误,也会引发额外的依赖注入问题。
解决方案
1. 拆分测试逻辑(最优方案)
PatientGroupComponent的单元测试不需要引入AppComponent,直接清理相关冗余代码即可:
- 删掉TestBed配置
declarations数组中的AppComponent - 删掉所有和
fixture1、AppComponent实例化相关的代码 - 路由导航测试属于路由配置校验逻辑,应该单独编写
app.component.spec.ts测试,不要和业务组件单测混合
2. 修正TestBed配置
- 删掉
providers中冗余的RouterOutlet、Router以及{ provide: Router, useClass: RouterModule }配置,RouterTestingModule已经默认提供了所有路由相关的测试依赖,不需要手动重复声明 - 不需要额外引入
RouterModule,直接使用RouterTestingModule.withRoutes()传入你的路由配置即可
3. 若确实需要在当前测试中使用AppComponent,二选一即可
- 方案1:在TestBed配置中添加
schemas: [CUSTOM_ELEMENTS_SCHEMA],忽略未识别的自定义标签 - 方案2:将
RouterTestingModule替换为RouterTestingModule.withRoutes(routes),传入项目的路由配置,即可正确识别<router-outlet>标签
修正后的单元测试示例代码
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; import { Location } from '@angular/common'; import { PatientGroupComponent } from './patient-group.component'; import { RouterTestingModule } from '@angular/router/testing'; import { HttpClientTestingModule } from '@angular/common/http/testing'; import { Routes, Router } from '@angular/router'; // 传入你的路由配置 const testRoutes: Routes = [ { path : '', redirectTo : 'patientGroup', pathMatch : 'full'}, { path : 'patientGroup', component : PatientGroupComponent} ]; describe('PatientGroupComponent', () => { let location : Location; let router : Router; let component: PatientGroupComponent; let fixture: ComponentFixture<PatientGroupComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ imports : [ RouterTestingModule.withRoutes(testRoutes), HttpClientTestingModule ], declarations: [ PatientGroupComponent ] }) .compileComponents(); location = TestBed.get(Location); router = TestBed.get(Router); router.initialNavigation(); })); beforeEach(() => { fixture = TestBed.createComponent(PatientGroupComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should navigate to /patientGroup', fakeAsync(()=>{ router.navigate(['']); tick(); expect(location.path()).toBe('/patientGroup'); })) it('should create', () => { // 注意:你原来的选择器写错了,group-btn是class,前面要加. const btn = fixture.debugElement.nativeElement.querySelector('.group-btn'); btn.click(); // group-data也是class,前面加. const h1 = fixture.debugElement.nativeElement.querySelector('.group-data') expect(h1.innerHTML).toBeTruthy(); }); });
注意:你原来的dom选择器写错了,group-btn和group-data是class属性,选择器前面需要加.才能匹配到对应元素
内容的提问来源于stack exchange,提问作者sukumar
相关产品推荐
相关产品推荐

