Angular 5 Jasmine单元测试报错:submitEl.triggerEventHandler不是函数
解决Angular 5 Jasmine单元测试中
triggerEventHandler is not a function错误 嘿,我一眼就揪出问题所在啦!你遇到的这个错误,根源是把DebugElement和原生DOM元素的用法搞混了。
问题原因
看你测试代码里的这一行:
submitEl = fixture.debugElement.query(By.css('button')).nativeElement;
你把DebugElement对应的原生DOM元素赋值给了submitEl,但triggerEventHandler是DebugElement专属的方法,原生DOM元素根本没有这个方法,自然会报错啦。
快速修复步骤
保留DebugElement类型,不要取nativeElement
把submitEl的赋值代码改成下面这样,让它保持DebugElement类型:submitEl = fixture.debugElement.query(By.css('button'));这样你就能正常调用
triggerEventHandler方法了。额外提醒:你当前测试的是Cancel按钮,不是提交按钮
看你的模板代码,表单的提交逻辑绑定在<form>标签的ngSubmit事件上,但你现在获取的是Cancel按钮(type="button"),点击它并不会触发表单提交哦!如果你的测试目标是触发表单提交,有两种方式可选:- 方式一:直接触发表单的ngSubmit事件
获取表单元素,直接调用triggerEventHandler触发提交:const formEl = fixture.debugElement.query(By.css('form')); formEl.triggerEventHandler('ngSubmit', null); - 方式二:添加提交按钮并测试它
先在模板里添加一个提交按钮:
然后在测试代码里获取这个提交按钮:<button type="submit" class="btn btn-primary">Save</button>submitEl = fixture.debugElement.query(By.css('button[type="submit"]')); submitEl.triggerEventHandler('click', null);
- 方式一:直接触发表单的ngSubmit事件
完善测试流程,同步表单模型
在设置输入框值之后,别忘了触发input事件通知Angular更新表单模型,不然ngModel不会同步,表单验证也会出问题:scopeValue.nativeElement.value = "test@example.com"; // 触发input事件同步模型 scopeValue.nativeElement.dispatchEvent(new Event('input')); // 触发变更检测 fixture.detectChanges();
修改后的完整测试代码片段
describe('ScopeEditorComponent', () => { let component: ScopeEditorComponent; let fixture: ComponentFixture<ScopeEditorComponent>; let submitEl: DebugElement; // 改为DebugElement类型 let scopeValue: DebugElement; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [ HttpClientModule, RouterTestingModule ], declarations: [ ScopeEditorComponent, SearchBoxComponent, GroupByPipe ] }); fixture = TestBed.createComponent(ScopeEditorComponent); component = fixture.componentInstance; // 这里确保service正确初始化(比如你之前的PermissionEndpointMock) fixture.detectChanges(); // 保留DebugElement,不要取nativeElement submitEl = fixture.debugElement.query(By.css('button')); scopeValue = fixture.debugElement.query(By.css('#scopename')); })); it('should create the scope component', async(() => { expect(component).toBeTruthy(); })); it('add scope', () => { let scope: Scope; // 设置输入值并同步表单模型 scopeValue.nativeElement.value = "test@example.com"; scopeValue.nativeElement.dispatchEvent(new Event('input')); fixture.detectChanges(); component.addscopeEventEmitter.subscribe((value) => scope = value); // 现在可以正常调用triggerEventHandler submitEl.triggerEventHandler('click', null); expect(scope.scopeid).toBe("123456"); }); });
内容的提问来源于stack exchange,提问作者Niranjan
相关产品推荐
相关产品推荐

