Angular单元测试:如何测试响应式表单reset方法?
解决Jest测试中"Cannot spyOn on a primitive value, undefined given"错误
问题场景
尝试测试组件中的如下方法:
doResetForm(){ this.form.reset(); }
编写的测试用例如下:
it('should reset the form', () => { const spyformReset = jest.spyOn(component.form, 'reset'); fixture.detectChanges(); component.doResetForm(); expect(spyformReset).toHaveBeenCalled(); }
执行测试时出现错误:
Cannot spyon on a primitive value, undefined give
错误原因
报错核心是执行jest.spyOn时,component.form的值为undefined,Jest无法对不存在的对象方法创建间谍。
解决方法
1. 提前初始化组件的form对象
在测试用例执行前,手动为component.form赋值一个包含reset方法的模拟对象:
it('should reset the form', () => { // 初始化模拟form对象 component.form = { reset: jest.fn() }; // 创建方法间谍 const spyformReset = jest.spyOn(component.form, 'reset'); component.doResetForm(); expect(spyformReset).toHaveBeenCalled(); });
2. 确保组件初始化后再创建间谍
如果是Angular等框架的组件,form通常在ngOnInit或模板初始化阶段创建,可调整测试流程确保form已初始化:
it('should reset the form', () => { // 触发组件初始化,确保form被创建 fixture.detectChanges(); // 此时form已存在,创建间谍 const spyformReset = jest.spyOn(component.form, 'reset'); component.doResetForm(); expect(spyformReset).toHaveBeenCalled(); });
若form在ngOnInit中初始化,也可手动调用该方法:
it('should reset the form', () => { // 手动调用ngOnInit初始化form component.ngOnInit(); const spyformReset = jest.spyOn(component.form, 'reset'); component.doResetForm(); expect(spyformReset).toHaveBeenCalled(); });
3. 框架级模拟(以Angular FormGroup为例)
如果组件使用Angular的FormGroup,可通过jest.mock全局模拟Form类:
import { FormGroup } from '@angular/forms'; // 模拟FormGroup,使其返回带有reset方法的对象 jest.mock('@angular/forms', () => ({ ...jest.requireActual('@angular/forms'), FormGroup: jest.fn(() => ({ reset: jest.fn() })) })); it('should reset the form', () => { fixture.detectChanges(); const spyformReset = jest.spyOn(component.form, 'reset'); component.doResetForm(); expect(spyformReset).toHaveBeenCalled(); });
内容的提问来源于stack exchange,提问作者paulotarcio
相关产品推荐
相关产品推荐

