Angular单元测试如何为MAT_DIALOG_DATA mock配置对应属性
核心问题定位
- 触发当前报错的直接原因:
MAT_DIALOG_DATA的mock值为空对象,没有覆盖组件ngOnInit中读取的全部嵌套属性结构。当组件代码执行到this.notification.payload.notification.title时,因为空对象不存在payload属性,payload值为undefined,再向下读取payload.notification就会抛出属性读取的类型错误。 - 存在的隐性配置错误:
MatDialogRef的依赖绑定写反了。测试代码中创建了dialogRefMock间谍对象,但在providers配置里给MatDialogRef绑定了从未初始化赋值的dialogMock变量,后续测试流程中只要调用弹窗关闭类方法,还会触发新的报错。
正确的配置调整步骤
- 修正
MatDialogRef的依赖绑定,将绑定值替换为已经初始化好的dialogRefMock间谍对象。 - 按照组件代码的属性读取链路,构造结构完全匹配的
MAT_DIALOG_DATAmock值,不要直接使用空对象。组件实际依赖的属性结构如下:// 完整匹配组件读取链路的mock结构 const mockDialogData = { frequency: 'realtime', topic: 'test-topic', // 对应 this.notification.time.seconds time: { seconds: 3600 }, // 对应 this.notification.day.day day: { day: 1 }, // 对应 this.notification.payload.notification.title / body payload: { notification: { title: '测试通知标题', body: '测试通知内容' } } } - 移除测试配置中对整个
AppModule的导入,单组件测试只需要保留组件实际依赖的最小模块集合即可,导入全量AppModule会引入不必要的依赖冲突、拖慢测试执行速度。
修正后的测试配置参考
fdescribe('NotificationsEditComponent', () => { let component: NotificationsEditComponent; let fixture: ComponentFixture<NotificationsEditComponent>; let dialogRefMock: jasmine.SpyObj<any>; // 提前定义结构匹配的弹窗mock数据 const mockDialogData = { frequency: 'daily', topic: 'system-alert', time: { seconds: 7200 }, day: { day: 1 }, payload: { notification: { title: '系统维护提醒', body: '系统将在凌晨2点进行升级维护' } } }; beforeEach(waitForAsync(() => { dialogRefMock = jasmine.createSpyObj('MatDialogRef', ['close']); TestBed.configureTestingModule({ imports: [ CommonModule, ReactiveFormsModule, FormsModule, MatDialogModule, MatFormFieldModule, MatInputModule, ], declarations: [ NotificationsEditComponent ], providers: [ // 修正绑定:使用正确初始化的dialogRefMock { provide: MatDialogRef, useValue: dialogRefMock }, // 替换空对象为结构匹配的mock数据 { provide: MAT_DIALOG_DATA, useValue: mockDialogData }, ] }).compileComponents(); })); });
注:配置完成后再执行组件初始化、变更检测的流程,就不会出现嵌套属性读取的报错了。
内容的提问来源于stack exchange,提问作者Vinicius Lustosa
相关产品推荐
相关产品推荐

