Angular测试报错:无法找到支持'[object Object]'的差异器
嘿,这个问题我太熟了!你看报错信息说得明明白白:NgFor只支持绑定数组这类可迭代对象,但你在测试用例里给MAT_DIALOG_DATA提供的是一个空对象{},而组件模板第一行就写了*ngFor="let item of data"——运行时组件能正常工作是因为实际业务中你传入的是数组,但测试环境里没给对数据,自然就报错了。
当然需要给测试提供符合结构的测试数据!
你要做的就是把测试里的MAT_DIALOG_DATA替换成一个模拟的数组,数组里的对象要匹配组件模板中用到的所有字段(不用填真实业务数据,用假值就行)。
具体修改步骤
- 先定义一个符合组件数据结构的模拟数组(比如叫
mockDialogData) - 在TestBed的providers里,把
MAT_DIALOG_DATA的useValue改成这个模拟数组
修改后的完整测试代码
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { TechniqueDetailsComponent } from './technique-details.component'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material'; describe('TechniqueDetailsComponent', () => { let component: TechniqueDetailsComponent; let fixture: ComponentFixture<TechniqueDetailsComponent>; // 模拟符合组件渲染要求的测试数据 const mockDialogData = [ { name: '测试技术', description: '这是一个测试用的技术描述', structure: { modules: [ { name: '测试模块', phases: [ { name: '测试阶段', tasks: [ { type: '测试任务类型', description: '测试任务描述', role: '测试角色', resources: '测试资源' } ] } ] } ] }, rules: ['测试规则1', '测试规则2'], target_audience: ['测试受众'], resolution_scope: ['测试范围'], delivery_mode: ['测试交付模式'], interaction: ['测试交互方式'], learning_objectives: [ { knowledge_category: '测试知识分类', behaviour: '测试行为目标' } ], affective_objectives: [], social_objectives: [] } ]; beforeEach(async(() => { TestBed.configureTestingModule({ declarations: [ TechniqueDetailsComponent ], providers: [ // 这里把空对象换成模拟的数组数据 { provide: MAT_DIALOG_DATA, useValue: mockDialogData } ], schemas: [ CUSTOM_ELEMENTS_SCHEMA ] }) .compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(TechniqueDetailsComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); });
额外优化建议
为了避免后续开发和测试时出现字段拼写错误,建议给组件的data定义一个TypeScript接口,这样类型检查能帮你提前发现问题:
在component.ts里添加这些接口:
// 定义数据结构的接口 interface Task { type: string; description: string; role: string; resources: string; } interface Phase { name: string; tasks: Task[]; } interface Module { name: string; phases: Phase[]; } interface LearningObjective { knowledge_category: string; behaviour: string; } interface Technique { name: string; description: string; structure: { modules: Module[] }; rules: string[]; target_audience: string[]; resolution_scope: string[]; delivery_mode: string[]; interaction: string[]; learning_objectives: LearningObjective[]; affective_objectives: string[]; social_objectives: string[]; } // 然后把组件里的data类型改成这个接口数组 @Component({ selector: 'app-technique-details', templateUrl: './technique-details.component.html', styleUrls: ['./technique-details.component.scss'] }) export class TechniqueDetailsComponent implements OnInit { constructor( @Inject(MAT_DIALOG_DATA) public data: Technique[] // 这里指定类型 ) { } ngOnInit() { } }
这样不管是开发还是写测试,都能清晰知道数据应该是什么结构,减少出错概率。
内容的提问来源于stack exchange,提问作者idetodospoca
相关产品推荐
相关产品推荐

