使用 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);
});
所以我试图添加两个测试以确保两个绑定实际上是为 属性 设置的。不确定我在这里错过了什么,但感觉我很接近。
这是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);
});