Angular组件单元测试报错:DynamicTestModule导入DecoratorFactory异常
解决Angular单元测试报错:"Unexpected value 'DecoratorFactory' imported by the module 'DynamicTestModule'"
错误根源
你把非NgModule类/装饰器/服务/工具类错误地放到了TestBed.configureTestingModule的imports数组中——这个数组只能接收带@NgModule装饰器的Angular模块,放其他类型的内容会导致测试模块无法识别,触发DecoratorFactory相关错误。
具体修复步骤
清理
imports数组
只保留真正的Angular模块,比如你的组件依赖的FormsModule和ReactiveFormsModule,其余所有非模块内容全部移除:imports: [ FormsModule, ReactiveFormsModule ]你之前添加的
Component、NavController、AccountProvider等都不属于模块,绝对不能放在imports里。修正
providers数组的写法
你当前providers里的{ provide: accountProvider, useValue: {} }写法错误,provide参数必须传入类本身,而非变量。同时,所有组件依赖的服务(导航、弹窗、自定义服务等)都要在这里提供模拟对象:providers: [ { provide: AccountProvider, useValue: {} }, { provide: NavController, useValue: {} }, { provide: ToastController, useValue: {} }, { provide: AlertController, useValue: {} }, { provide: GlobalProvider, useValue: {} }, { provide: HttpClient, useValue: {} } ]如果需要模拟服务的方法,可以用
jasmine.createSpyObj创建带间谍的模拟对象(示例代码里有演示)。移除冗余导入
测试文件里不需要导入Component、FormGroup、Validators、phoneValidation这些(除非你在测试逻辑里直接用到),可以直接删除这些导入语句,减少代码冗余。
修复后的完整测试代码
import { HttpClient } from '@angular/common/http'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from "@angular/core/testing"; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { AlertController, NavController, ToastController } from '@ionic/angular'; import { GlobalProvider } from 'src/app/services/app/global'; import { AccountProvider } from 'src/app/services/profile/account'; import { AccountDetailsPage } from "./account-details"; describe("AccountDetailsPage", () => { let component: AccountDetailsPage; let fixture: ComponentFixture<AccountDetailsPage>; let accountProvider: jasmine.SpyObj<AccountProvider>; beforeEach(async () => { // 创建带间谍的AccountProvider模拟对象(按需添加需要模拟的方法) const accountProviderSpy = jasmine.createSpyObj('AccountProvider', ['updateProfile']); await TestBed.configureTestingModule({ declarations: [AccountDetailsPage], schemas: [CUSTOM_ELEMENTS_SCHEMA], providers: [ { provide: AccountProvider, useValue: accountProviderSpy }, { provide: NavController, useValue: {} }, { provide: ToastController, useValue: {} }, { provide: AlertController, useValue: {} }, { provide: GlobalProvider, useValue: {} }, { provide: HttpClient, useValue: {} } ], imports: [ FormsModule, ReactiveFormsModule ] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(AccountDetailsPage); component = fixture.componentInstance; // 获取注入的服务实例 accountProvider = TestBed.inject(AccountProvider) as jasmine.SpyObj<AccountProvider>; fixture.detectChanges(); }); describe('组件初始化', () => { it('应成功创建组件实例', () => { expect(component).toBeTruthy(); }); }); })
内容的提问来源于stack exchange,提问作者Jerome Garcia
相关产品推荐
相关产品推荐

