You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:24:24