测试来自 Angular 响应式表单的提交数据
Testing submitted data from Angular Reactive form
基于 https://angular.io/guide/reactive-forms 中的第一个示例,我创建了以下哑组件:
@Component({
selector: 'app-name-editor',
templateUrl: './name-editor.component.html',
styleUrls: ['./name-editor.component.css']
})
export class NameEditorComponent {
name = new FormControl('');
@Output('submitted') submitted = new EventEmitter<string>();
onSubmit() { this.submitted.emit(this.name.value); }
}
... 我想为此编写一个单元测试来验证是否提交了值。这使用 https://angular.io/guide/testing#component-inside-a-test-host 中建议的 TestHost :
@Component({
template: `
<app-name-editor (submitted)=onSubmit($event)>
</app-name-editor>
`})
class TestHostComponent {
submitted: string;
onSubmit(data: string) { this.submitted = data; }
}
describe('NameEditorComponent', () => {
let testHost: TestHostComponent;
let fixture: ComponentFixture<TestHostComponent>;
let editorDebugElt: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ NameEditorComponent, TestHostComponent ]
});
fixture = TestBed.createComponent(TestHostComponent);
testHost = fixture.componentInstance;
editorDebugElt = fixture.debugElement.query(By.directive(NameEditorComponent));
fixture.detectChanges();
});
it('should capture data', () => {
const compiled = fixture.debugElement.nativeElement;
const nameInput = compiled.querySelector('input[type="text"]');
expect(nameInput).toBeTruthy();
nameInput.value = 'This is a test';
fixture.detectChanges();
// Find submit button
const submitInput = compiled.querySelector('input[type="submit"]');
expect(submitInput).toBeTruthy();
// Trigger click action
expect(testHost.submitted).toBeFalsy();
submitInput.click();
// Submitted
expect(testHost.submitted).toBe('This is a test');
});
});
测试失败,但我不明白为什么。输入中填充了测试结果下方所示的值。非常感谢任何帮助。
而不是检查提交 'This is a test'。您可以监视 testHost.submitted 中的 emit 方法并检查它是否使用表单控件的值调用。
it('should capture data', () => {
const compiled = fixture.debugElement.nativeElement;
spyOn(testHost.submitted, 'emit')
testHost.name.value('This is a test')
const submitInput = compiled.querySelector('input[type="submit"]');
submitInput.click();
expect(testHost.submitted.emit).toHaveBeenCalled();
expect(testHost.submitted.emit).toHaveBeenCalledWith(testHost.name.value)
});
表单提交空白值的原因是因为反应式表单是异步的。
编辑表单并在之后立即提交将提交空白表单,因为编辑是异步进行的。测试现在通过添加 500 毫秒的等待时间来通过,但是如果知道如何避免等待就更好了:
// Wait for asynchronous update on reactive form to happen
setTimeout(() => {
// Trigger click action
expect(testHost.submitted).toBeFalsy();
submitInput.click();
// Submitted
expect(testHost.submitted).toBe('This is a test');
}, 500);
基于 https://angular.io/guide/reactive-forms 中的第一个示例,我创建了以下哑组件:
@Component({
selector: 'app-name-editor',
templateUrl: './name-editor.component.html',
styleUrls: ['./name-editor.component.css']
})
export class NameEditorComponent {
name = new FormControl('');
@Output('submitted') submitted = new EventEmitter<string>();
onSubmit() { this.submitted.emit(this.name.value); }
}
... 我想为此编写一个单元测试来验证是否提交了值。这使用 https://angular.io/guide/testing#component-inside-a-test-host 中建议的 TestHost :
@Component({
template: `
<app-name-editor (submitted)=onSubmit($event)>
</app-name-editor>
`})
class TestHostComponent {
submitted: string;
onSubmit(data: string) { this.submitted = data; }
}
describe('NameEditorComponent', () => {
let testHost: TestHostComponent;
let fixture: ComponentFixture<TestHostComponent>;
let editorDebugElt: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ NameEditorComponent, TestHostComponent ]
});
fixture = TestBed.createComponent(TestHostComponent);
testHost = fixture.componentInstance;
editorDebugElt = fixture.debugElement.query(By.directive(NameEditorComponent));
fixture.detectChanges();
});
it('should capture data', () => {
const compiled = fixture.debugElement.nativeElement;
const nameInput = compiled.querySelector('input[type="text"]');
expect(nameInput).toBeTruthy();
nameInput.value = 'This is a test';
fixture.detectChanges();
// Find submit button
const submitInput = compiled.querySelector('input[type="submit"]');
expect(submitInput).toBeTruthy();
// Trigger click action
expect(testHost.submitted).toBeFalsy();
submitInput.click();
// Submitted
expect(testHost.submitted).toBe('This is a test');
});
});
测试失败,但我不明白为什么。输入中填充了测试结果下方所示的值。非常感谢任何帮助。
而不是检查提交 'This is a test'。您可以监视 testHost.submitted 中的 emit 方法并检查它是否使用表单控件的值调用。
it('should capture data', () => {
const compiled = fixture.debugElement.nativeElement;
spyOn(testHost.submitted, 'emit')
testHost.name.value('This is a test')
const submitInput = compiled.querySelector('input[type="submit"]');
submitInput.click();
expect(testHost.submitted.emit).toHaveBeenCalled();
expect(testHost.submitted.emit).toHaveBeenCalledWith(testHost.name.value)
});
表单提交空白值的原因是因为反应式表单是异步的。
编辑表单并在之后立即提交将提交空白表单,因为编辑是异步进行的。测试现在通过添加 500 毫秒的等待时间来通过,但是如果知道如何避免等待就更好了:
// Wait for asynchronous update on reactive form to happen
setTimeout(() => {
// Trigger click action
expect(testHost.submitted).toBeFalsy();
submitInput.click();
// Submitted
expect(testHost.submitted).toBe('This is a test');
}, 500);