如何测试简单的Angular反应形式

时间:2018-12-29 23:27:50

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

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

这是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);
  });

尽管在我看来,该测试并未完全反映我要模拟的内容,即单击按钮。另一方面,如果我尝试实际模拟按钮上的click事件,则无法创建成功的测试。例如,以下测试未通过

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中测试表单的信息。

1 个答案:

答案 0 :(得分:0)

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

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

试试

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

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

不幸的是,这不会测试模板和组件之间的绑定。