在单元测试中调度输入事件时,永远不会触发表单的值更改
Value changes of a form is never triggered when dispatching an input event in a unit test
我正在尝试测试当我在输入中键入时表单上的值是否发生了变化。
项目使用的是Nrwl nx,测试工具是jest
分量:
export class InputNumericComponent implements OnInit, OnDestroy {
@Input() form: FormGroup;
@Input() controlName: string;
private _changeSubscription: Subscription;
private get _control(): AbstractControl | null {
return this.form?.get(this.controlName);
}
public ngOnInit(): void {
if (!this._control) {
return;
}
console.log('init called'); // ok
this._changeSubscription = this._control.valueChanges
.pipe(tap((newValue) => this._handleChange(newValue)))
.subscribe();
}
public ngOnDestroy(): void {
if (this._changeSubscription) {
this._changeSubscription.unsubscribe();
}
}
private _handleChange(value: string): void {
console.log('_handleChange'); // never called
}
public handleBlur(): void {
console.log('handleBlur'); // can be called by using dispatchEvent(new Event('blur'));
}
}
测试文件:
describe('InputNumericComponent', () => {
let component: InputNumericComponent;
let fixture: ComponentFixture<InputNumericComponent>;
configureTestSuite(() => {
TestBed.configureTestingModule({
declarations: [InputNumericComponent],
schemas: [NO_ERRORS_SCHEMA],
});
});
beforeEach(() => {
fixture = TestBed.createComponent(InputNumericComponent);
component = fixture.componentInstance;
component.controlName = 'numeric';
component.form = new FormGroup({
numeric: new FormControl(),
});
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should update form', fakeAsync(() => {
component.ngOnInit();
const input = fixture.debugElement.query(By.css('input'));
input.nativeElement.value = '222';
// i tried both and others like keydown, keypress, etc..
input.nativeElement.dispatchEvent(new Event('change'));
input.nativeElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
tick();
console.log('form', component.form.get('numeric')?.value); // null
expect(input.form.get('numeric')).toEqual('222');
}));
});
我不知道为什么但输入事件不会触发 valueChanges
,如果我发送 blur
事件 handleBlur
函数被调用但我没有知道如何触发 valueChanges
,我试过 keydown
、keypress
。
我尝试直接在输入上发送一个输入事件并且它有效,_handleChange
被调用但不知道为什么在测试中它不起作用。
我试过使用 fixture.nativeElement.querySelector('input')
的其他方法,但它也不起作用。
我做错了什么?
将 ReactiveFormsModule
添加到您的 TestBed 导入。
我正在尝试测试当我在输入中键入时表单上的值是否发生了变化。 项目使用的是Nrwl nx,测试工具是jest
分量:
export class InputNumericComponent implements OnInit, OnDestroy {
@Input() form: FormGroup;
@Input() controlName: string;
private _changeSubscription: Subscription;
private get _control(): AbstractControl | null {
return this.form?.get(this.controlName);
}
public ngOnInit(): void {
if (!this._control) {
return;
}
console.log('init called'); // ok
this._changeSubscription = this._control.valueChanges
.pipe(tap((newValue) => this._handleChange(newValue)))
.subscribe();
}
public ngOnDestroy(): void {
if (this._changeSubscription) {
this._changeSubscription.unsubscribe();
}
}
private _handleChange(value: string): void {
console.log('_handleChange'); // never called
}
public handleBlur(): void {
console.log('handleBlur'); // can be called by using dispatchEvent(new Event('blur'));
}
}
测试文件:
describe('InputNumericComponent', () => {
let component: InputNumericComponent;
let fixture: ComponentFixture<InputNumericComponent>;
configureTestSuite(() => {
TestBed.configureTestingModule({
declarations: [InputNumericComponent],
schemas: [NO_ERRORS_SCHEMA],
});
});
beforeEach(() => {
fixture = TestBed.createComponent(InputNumericComponent);
component = fixture.componentInstance;
component.controlName = 'numeric';
component.form = new FormGroup({
numeric: new FormControl(),
});
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should update form', fakeAsync(() => {
component.ngOnInit();
const input = fixture.debugElement.query(By.css('input'));
input.nativeElement.value = '222';
// i tried both and others like keydown, keypress, etc..
input.nativeElement.dispatchEvent(new Event('change'));
input.nativeElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
tick();
console.log('form', component.form.get('numeric')?.value); // null
expect(input.form.get('numeric')).toEqual('222');
}));
});
我不知道为什么但输入事件不会触发 valueChanges
,如果我发送 blur
事件 handleBlur
函数被调用但我没有知道如何触发 valueChanges
,我试过 keydown
、keypress
。
我尝试直接在输入上发送一个输入事件并且它有效,_handleChange
被调用但不知道为什么在测试中它不起作用。
我试过使用 fixture.nativeElement.querySelector('input')
的其他方法,但它也不起作用。
我做错了什么?
将 ReactiveFormsModule
添加到您的 TestBed 导入。