使用 Jest 在 Angular 中测试双向绑定

Testing two way binding in Angular with Jest

所以我试图添加两个测试以确保两个绑定实际上是为 属性 设置的。不确定我在这里错过了什么,但感觉我很接近。

这是html:

   <input [(ngModel)]="value" (change)="onChange()"/>

这是组件 class:

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'cs-string-field',
  templateUrl: './string-field.component.html',
  styleUrls: ['./string-field.component.scss']
})
export class StringFieldComponent implements OnInit {
  @Input() value: string;

  @Output() change = new EventEmitter<string>();
  constructor() { }

  ngOnInit(): void {
  }

  onChange = () => this.change.emit(this.value);
}

最后但并非最不重要的是我的测试。最后一个失败了:

import { ComponentFixture, TestBed } from '@angular/core/testing';

import { StringFieldComponent } from './string-field.component';
import { FormsModule } from '@angular/forms';

describe('StringFieldComponent', () => {
  let component: StringFieldComponent;
  let fixture: ComponentFixture<StringFieldComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ StringFieldComponent ],
      imports: [FormsModule]
    })
    .compileComponents();
  });

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should have an input tag with type text', () => {

    const sut = fixture.nativeElement
      .querySelector('input[type="text"]');

    expect(sut).toBeTruthy();
  });

  it('should emit a value on change', done => {
    const value = "Pretty Kitty";
    const event = new Event('change');
    component.value = value;
    fixture.detectChanges();
    const ele = fixture.nativeElement
      .querySelector('input[type="text"]');

    component.change.subscribe(res => {
      expect(res).toBe(value);
      done();
    })

    ele.dispatchEvent(event);
  });

  it('should update value on input', done => {
    const value = "Pretty Kitty";
    const event = new Event('change');
    component.value = '';
    fixture.detectChanges();
    const ele = fixture.nativeElement
      .querySelector('input[type="text"]');

    component.change.subscribe(res => {
      expect(res).toBe(value);
      done();
    })

    ele.value = value;
    ele.dispatchEvent(event);
  });
});

我觉得我在这里遗漏了一些非常简单的东西,但是组件上没有设置值。

所以我花了比我想承认看到这个时间更长的时间,但最后一次测试遗漏了一件事。必须触发输入事件才能使两个绑定起作用。所以这是正确的测试,我现在恢复了理智。

  it('should update value on input', done => {
    const value = "Pretty Kitty";
    const inputEvent = new Event('input');
    const event = new Event('change');
    component.value = '';
    fixture.detectChanges();
    const ele = fixture.nativeElement
      .querySelector('input[type="text"]');

    component.change.subscribe(res => {
      expect(res).toBe(value);
      done();
    })

    ele.value = value;
    ele.dispatchEvent(inputEvent);
    ele.dispatchEvent(event);
  });