typescript - วิธีการจำลอง ngControl ใน Custom Form Control - การทดสอบหน่วย Angular
ฉันกำลังมองหาตัวอย่างที่มี unit tests สำหรับ Custom Form Control ใน Angular 9 ส่วนนี้ constructor(@Self() private ngControl: NgControl) ทำให้เกิดข้อผิดพลาด: Error: NodeInjector: NOT_FOUND [NgControl] เนื่องจากฉันจำเป็นต้องตั้งค่า value accessor บางวิธี
ฉันกำลังฉีด ngControl ใน constructor เนื่องจากฉันจำเป็นต้องใช้ ngControl ในคอมโพเนนต์ของฉันในภายหลัง นั่นคือสาเหตุที่ฉันไม่ได้ใช้การใช้งานแบบปกติกับ provide: NG_VALUE_ACCESSOR
ฉันกำลังพยายามล้อเลียนมันโดย:
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [
{ provide: NgControl, useValue: new FormControlDirective([], [], [], null) }
],
imports: [FormsModule, ReactiveFormsModule]
}).compileComponents();
แต่ฉันมีข้อผิดพลาด: No valid value accessor for form control with unspecified name attribute เนื่องจากฉันไม่รู้ว่าควรจะใส่อะไรในพารามิเตอร์ตัวที่ 3 ของฟังก์ชัน FormControlDirective ซึ่งคือ: valueAccessors: ControlValueAccessor[]
มีใครมีไอเดียไหมว่าฉันจะจำลองสิ่งนี้ได้อย่างไร?
คำตอบ #1
ลองล้อเลียนมันแบบนี้:
let mockNgControl: any;
beforeEach(async(() => {
mockNgControl = jasmine.createSpyObj('ngControl', ['value', /* mock other methods required here */]);
TestBed.configureTestingModule({
providers: [
{ provide: NgControl, useValue: mockNgControl }
],
imports: [FormsModule, ReactiveFormsModule]
}).compileComponents();
คำตอบ #2
เนื่องจาก FormControlName ขยายมาจาก NgControl คำตอบที่ยอมรับจะล้มเหลวถ้ามีการเรียกใช้เมธอดใด ๆ ของ ControlValueAccessor (ดูเพิ่มเติมที่นี่) เช่น writeValue()
ตัวอย่างเช่น หนึ่งในการทดสอบของโครงการของเราจะเขียน "ค่าที่ใหม่" เมื่อฟัง ngModelChange เช่นนี้:
this.ngControl.valueAccessor.writeValue(newVal);
แต่เมทอด jasmine.createSpyObj('ngControl', [...]) ล้มเหลวที่นี่ แม้ว่าได้กำหนด writeValue เป็น valueAccessor: { writeValue:() => null } ในอ็อบเจ็กต์สปายแล้ว ผมพบว่าง่ายกว่าที่จะจำลอง ngControl ดังนี้:
let mockNgControl: NgControl = new FormControlName(null, null, null, [{writeValue: () => null, registerOnChange: () => null, registerOnTouched: () => null}], null);
เพราะที่นี่คือตัวสร้างสำหรับ FormControlName
constructor(
parent: ControlContainer,
validators: (Validator | ValidatorFn)[],
asyncValidators: (AsyncValidator | AsyncValidatorFn)[],
**valueAccessors: ControlValueAccessor[],**
_ngModelWarningConfig: string | null
);
จากนั้น ngControl ของฉันสามารถถูกส่งเข้าไปในตัวสร้างของไดเร็กทีฟแบบนี้:
let alphanumericDirective = new AlphanumericDirective(mockNgControl);
