【问题标题】:How to test a simple Angular Reactive Form如何测试一个简单的 Angular 响应式表单
【发布时间】:2019-05-27 04:47:41
【问题描述】:

我有一个组件,它包含一个非常简单的响应式表单,只有一个输入字段和一个用于提交表单的按钮。

这里是html模板的代码

<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <input type="text" formControlName="idControl">
  <button type="submit" class="button" [disabled]="myForm.invalid">Submit Form</button>
</form>

这里是组件代码中的 FormGroup

@Component({
  selector: 'my-form',
  templateUrl: './my-form.component.html',
  styleUrls: ['./my-form.component.scss']
})
export class MyFormComponent implements OnInit {
  myForm = new FormGroup({
    idControl: new FormControl('' , [
      Validators.required
    ])
  });
.....
.....
}

现在我想为这个组件写一个简单的测试,一个测试基本上说

  • 首先将输入字段的值设置为“Blah”
  • 然后点击按钮提交表单
  • 最后检查,点击按钮后, 名为 idControl 的控件实际上是“Blah”

下面的测试示例确实有效

it('1.1 should update the value of the input field after an "input" event on the input field', () => {
    const inputVal = 'Blah';
    const input = fixture.nativeElement.querySelector('input');
    input.value = inputVal;

    input.dispatchEvent(new Event('input'));

    expect(fixture.componentInstance.myForm.value.idControl).toEqual(inputVal);
  });

在我看来,这个测试并不能准确反映我想要模拟的内容,即单击按钮。另一方面,如果我尝试实际模拟按钮上的单击事件,则无法创建成功的测试。比如下面的测试没有通过

it('1.2 should update the value of the input field after a "submit" event on the form', () => {
    const inputVal = 'Blah1';
    const input = fixture.nativeElement.querySelector('input');
    input.value = inputVal;
    const submitEl = fixture.debugElement.query(By.css('button'));
    submitEl.triggerEventHandler('click', null);
    fixture.detectChanges();

    expect(fixture.componentInstance.myForm.value.idControl).toEqual(inputVal);
  });

我也尝试了不同的变体,例如使用

fixture.debugElement.query(By.css('button')).nativeElement.click();

但似乎没有任何效果。

这是我使用的测试配置代码

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ InputFormComponent],
      imports: [ReactiveFormsModule]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(InputFormComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

我的问题是我是否遗漏了有关如何在 Angular 中测试表单的内容。

【问题讨论】:

  • 快速思考 - 您可能需要一个 fixture.whenStable().then(() =&gt; { fixture.detectChanges(); /* now test */ }) 以允许按钮在单击之前在屏幕上呈现。

标签: angular angular-reactive-forms angular-forms angular-test


【解决方案1】:

不是初始问题的解决方案,但我找到了至少一种更改输入值的方法。而不是

const input = fixture.nativeElement.querySelector('input');
input.value = inputVal;

试试

component.formControl.setValue(inputVal, { emitEvent: true });

emitEvent 选项可确保不仅更改值,而且触发事件,就像用户刚刚键入它一样。

很遗憾,这不会测试模板和组件之间的绑定。

【讨论】:

    猜你喜欢
    • 2017-03-14
    • 2021-02-28
    • 2018-06-04
    • 1970-01-01
    • 2014-08-13
    • 2020-06-16
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    相关资源
    最近更新 更多