Angular Jasmine测试@ViewChild模态框报element.close不存在如何解决
报错根因
单元测试环境下没有正确初始化@ViewChild对应的ModalDefaultComponent实例,你调用的close方法内部会访问传入的模态框实例的close方法,测试时这个方法不存在,所以抛出了类型错误。
解决方法
你可以选择以下两种方式任意一种来mock模态框实例:
方式1:直接手动给ViewChild赋值mock对象(最简单)
- 在测试文件的
describe块内定义mock模态框对象,预留需要的close方法spy:
// 适配Jasmine,用Jest的话把jasmine.createSpy换成jest.fn()即可 const mockConfirmModal = { close: jasmine.createSpy('modalClose') };
- 在
beforeEach的组件初始化逻辑后,手动给组件的confirmDelete属性赋值:
beforeEach(() => { // 保留你原有的TestBed配置、组件实例化逻辑 fixture = TestBed.createComponent(你的组件类); component = fixture.componentInstance; // 新增这行,给ViewChild手动注入mock实例 component.confirmDelete = mockConfirmModal as ModalDefaultComponent; fixture.detectChanges(); });
方式2:注册mock子组件(更符合Angular测试规范)
如果要模拟完整的子组件渲染逻辑,可以声明mock子组件替换真实的ModalDefaultComponent:
- 定义mock子组件:
@Component({ selector: 'app-modal-default', template: '' }) class MockModalDefaultComponent { close = jasmine.createSpy('close'); }
- 在TestBed的配置中声明这个mock组件:
TestBed.configureTestingModule({ declarations: [ 你要测试的组件类, MockModalDefaultComponent // 替换原来的真实ModalDefaultComponent ], // 保留你原有的providers等其他配置 }).compileComponents();
修正测试用例
你原来的用例多余手动调用了storeSpy.dispatch,而且fakeAsync不需要搭配done参数,修正后代码:
it('调用WMS删除动作应该符合预期', fakeAsync(() => { component.confirmDeleteOk(); // 验证store的dispatch被正确调用 expect(storeSpy.dispatch).toHaveBeenCalledWith(new DeleteWMS()); // 可选:如果需要验证模态框确实被关闭,可以加这行断言 expect(mockConfirmModal.close).toHaveBeenCalled(); }));
内容的提问来源于stack exchange,提问作者Shabeer M
相关产品推荐
相关产品推荐

