Jasmine测试中点击表单提交按钮触发整页重载问题排查
解决Jasmine测试中点击表单提交按钮触发页面重载的问题
问题场景
Angular组件的表单代码如下:
<form [formGroup]="articleForm" (ngSubmit)="addArticle()"> <div class="body"> [...] </div> <input type="submit" name="button" value="'article.add'"/> </form>
点击提交按钮会触发组件内的addArticle方法:
addArticle() { if(this.articleForm.valid) { [...] } else { this.articleForm.markAllAsTouched(); } }
编写的Jasmine测试用例模拟点击按钮:
it('Test', () => { let button = fixture.debugElement.query(By.css('input[name^="button"]')).nativeElement; button.click(); });
测试运行时出现错误:
Chrome 101.0.4951.54 (Linux x86_64) ERROR Some of your tests did a full page reload!
手动操作组件功能正常,直接调用addArticle函数测试也无异常,仅点击提交按钮测试时触发该问题。
问题原因
在Angular测试环境中,点击表单的submit按钮时,除了触发绑定的(ngSubmit)事件外,浏览器默认的表单提交行为(页面重载)也会被触发。手动操作时Angular框架会自动阻止这个默认行为,但Jasmine测试的模拟点击场景中,该默认行为未被拦截,导致页面重载,进而引发测试的无限循环或报错。
解决方法
可以通过以下几种方式解决:
- 方法1:在测试中阻止表单默认提交行为
it('Test', () => { const form = fixture.debugElement.query(By.css('form')); spyOn(form.nativeElement, 'submit').and.callFake((e) => { e.preventDefault(); // 拦截默认页面重载行为 }); const button = fixture.debugElement.query(By.css('input[name^="button"]')).nativeElement; button.click(); fixture.detectChanges(); });
- 方法2:直接触发
ngSubmit事件
跳过点击按钮的步骤,直接触发表单的ngSubmit事件,避免触发浏览器默认行为:
it('Test', () => { const form = fixture.debugElement.query(By.css('form')); form.triggerEventHandler('ngSubmit', null); fixture.detectChanges(); });
- 方法3:在组件方法中显式阻止默认行为
修改组件的addArticle方法,接收事件参数并拦截默认行为:
addArticle(event: Event) { event.preventDefault(); // 阻止默认提交行为 if(this.articleForm.valid) { [...] } else { this.articleForm.markAllAsTouched(); } }
同时更新模板中的事件绑定:
<form [formGroup]="articleForm" (ngSubmit)="addArticle($event)">
内容的提问来源于stack exchange,提问作者Slereah
相关产品推荐
相关产品推荐

