Prueba unitaria de Angular: Error: No hay acceso al valor del control del formulario.
Estoy abstrayendo cada campo de mi formulario de la siguiente manera (esto funciona en desarrollo pero no en mi prueba unitaria)
// required.control.ts
import { FormControl, Validators } from '@angular/forms';
export class RequiredControl extends FormControl {
protected textErrors: { [key: string]: string } = {
required: 'Campo obligatorio'
};
constructor(value: string | any = '') {
super(value);
this.setValidators([Validators.required]);
}
get textError() {
let message = '';
for (const error in this.textErrors) {
if (error && this.hasError(error) && this.dirty) {
message = this.textErrors;
return message;
}
}
return message;
}
get state() {
return this.valid || !this.dirty ? '' : 'error';
}
}
De esta manera puedo limpiar mi formulario y llevar la lógica de validación de cada campo a un archivo separado. Ahora, en el componente principal importo este archivo:
// my-component.component.ts
import { RequiredControl } from './required.control.ts';
@Component({})
export class MyComponent implements OnInit {
reasonControl = new RequiredControl(null);
constructor() {}
ngOnInit() {
this.requestForm = this.formBuilder.group({
reason: this.reasonControl, // primer método intentado :(
reason:this.reasonControl as FormControl, // segundo método intentado :(
});
}
}
En mis pruebas unitarias tengo lo siguiente:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyComponent],
imports: [ReactiveFormsModule, FormsModule, RouterTestingModule]
})
}));
Tengo esto en mi plantilla:
Cuando ejecuto esta prueba, obtengo el siguiente error:
davy.ai
El problema en el código proporcionado es que la clase
RequiredControl
extiende deFormControl
pero no se exporta comoFormControl
. Por lo tanto, cuando se utiliza en el componente, elFormGroup
no puede reconocerlo como un control de formulario válido.Para solucionar este problema, la clase
RequiredControl
puede implementar la interfazControlValueAccessor
, lo que le permite actuar como un control de formulario que se puede utilizar conFormGroup
. Aquí hay una versión actualizada de la claseRequiredControl
:En esta versión actualizada, la clase
RequiredControl
implementa la interfazControlValueAccessor
, lo que requiere que implemente varios métodos que le permiten interactuar con elFormGroup
. Además, la clase ahora tiene un selector y una plantilla que le permiten ser utilizados directamente en HTML.Para utilizar
RequiredControl
en el componente, simplemente puedes importarlo y agregarlo alFormGroup
de la siguiente manera:En esta versión actualizada,
RequiredControl
se agrega como una directiva al elementoinput
utilizando el selectorapp-required-control
. Esto permite que elFormGroup
reconozca y valide la entrada como un control de formulario.