問題
當我重構物件的成員時,我對表單中斷進行了單元測驗,因為我只能使用括號表示法訪問來自組的表單控制元件。這種基于字串的被測成員選擇不會被任何 IDE 用代碼重構。
這是一個例子......
物體:
class Task {
constructor(
public id: number = 0,
public description: string = '', // <--- member under test
public completed: boolean = false,
public priority: Priority = Priority.Normal
) {}
clone(): Task {
return new Task(this.id, this.description, this.completed, this.priority);
}
}
組件:
export class AppComponent implements OnInit {
form!: FormGroup;
task: Task;
priorities = [Priority.Low, Priority.Normal, Priority.High];
constructor(private fb: FormBuilder) {
this.task = this.mockTask();
}
ngOnInit() {
this.task = this.mockTask();
this.form = this.fb.group({
description: [
this.task.description,
Validators.compose([Validators.required, Validators.maxLength(50)]),
],
priority: [this.task.priority],
});
}
// ...
}
考試:
describe('AppComponent', () => {
let comp: AppComponent
let fixture: ComponentFixture<AppComponent>;
let task: Task;
let taskService: TaskService;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [AppComponent],
providers: [{provide: TaskService, useClass: MockTaskService}]
}).compileComponents()
}))
beforeEach((done) => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
taskService = fixture.debugElement.injector.get(TaskService);
taskService.getAllTasks().subscribe(tasks => {
task = tasks[0];
comp.task = task;
comp.ngOnInit();
fixture.detectChanges();
done()
})
})
it('should not update value if form is invalid', () => {
let spy = spyOn(taskService, 'updateTask')
comp.form.controls['description'].setValue(null) // <------
comp.onSubmit()
expect(comp.form.valid).toBeFalsy();
expect(spy).not.toHaveBeenCalled();
})
})
注意箭頭旁邊的括號符號。我希望能夠以某種方式使用它:
comp.form.controls.description.setValue(null)
我試過的
我嘗試創建一些界面,例如:
interface ITask {
description: string;
}
interface ITaskFormGroup extends FormGroup {
value: ITask;
controls: {
description: AbstractControl;
};
}
問題在于控制元件是 AbstractControl 型別,而相關任務的成員是字串型別。所以“控制元件”不能將 ITask 實作為通用介面。
另外,這個:
"compilerOptions": {
"noPropertyAccessFromIndexSignature": false,
// ...
}
...允許使用點表示法,但是當我更改 Task 或 ITask 中的成員“描述”時,這仍然不會重構測驗。
我覺得這個問題應該有一些解決方案,但我可以使用一些幫助到達那里。我想知道這需要付出什么努力,這樣我才能看看從長遠來看是否值得。
完整示例
盡管我認為您不能在Stackblitz上使用 Test runner ,但我提供了一個更完整的示例。為了解決語法問題,不需要運行測驗。
uj5u.com熱心網友回復:
從 FormGroup 獲取表單控制元件的正確方法是使用它的get函式:
const descControl = comp.form.get('description')
descControl.setValue(null)
這樣,如果缺少表單控制元件,至少您的測驗會引發錯誤。
Angular 團隊已經實作了強型別表單。如果您有耐心等待 angular 14,這也可以幫助您改進測驗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/477583.html
