Angular测试中读取MAT_DIALOG_DATA值返回undefined如何解决
取值为undefined的核心原因是MAT_DIALOG_DATA传值结构和组件接收的结构不匹配。
这里是Angular Material弹窗单元测试的高频踩坑点:平时调用MatDialog.open(Component, { data: { lastName: 'cc' } })打开弹窗时,外层的data是open方法的配置字段,Angular Material内部会自动把这个配置项里的data值抽出来作为MAT_DIALOG_DATA的注入内容,组件里注入拿到的直接就是{ lastName: 'cc' },不会带外层的配置包裹。
你的组件中@Inject(MAT_DIALOG_DATA)注入的对象会直接赋值给类属性data,data的类型是DialogData,该接口直接定义了lastName等字段,不存在外层data嵌套。但测试配置中给MAT_DIALOG_DATA传入的是{ data: { lastName: 'cc' } },最终组件实例上的data属性结构为:
{ data: { lastName: 'cc' } }
此时直接访问component.data.lastName自然得到undefined,实际lastName存在于component.data.data.lastName路径下,和DialogData的类型定义完全不符。
调整测试配置中MAT_DIALOG_DATA的传值结构,去掉多余的外层data包裹,和DialogData结构保持一致即可:
{ provide: MAT_DIALOG_DATA, useValue: { lastName: 'cc', currentDocument: 'test' // DialogData中该字段为必填项,补上避免类型校验报错 } as DialogData, }
修改后访问component.data.lastName即可正常拿到预期值'cc'。
- 当前给MatDialogRef传入的mock值是空对象
{},如果测试过程中调用组件的closeModal方法,会触发close is not a function报错,建议补充基础mock实现:
{ provide: MatDialogRef, useValue: { close: () => {} } }
- 确认测试模块导入的依赖不会覆盖你手动配置的provider,不要重复导入已经内置了MAT_DIALOG_DATA、MatDialogRef默认实现的模块,避免自定义传值被覆盖。
内容的提问来源于stack exchange,提问作者3gwebtrain

