我有一个采用模板驱动形式的组件
<form (ngSubmit)="onSearchCorpus(form)" #form="ngForm">
<combo-box [(ngModel)]="model.corpus" name="corpus" #corpus="ngModel"></combo-box>
<input [(ngModel)]="model.label" name="label" id="label" type="text" required pattern="^(?!\s*$)[\w\_\-\:\s]*" maxlength="50" class="form-control label-name" autocomplete="off" #label="ngModel">
<textarea [(ngModel)]="model.query" name="query" id="query" maxlength="3600" required validateQuerySyntax class="form-control search-query" #query="ngModel" #queryControl
placeholder="Example: ("grantee" OR "grant" OR "sponsor" OR "contribute" OR "contributor") NEAR ("non-profit organization" OR "charities")">
</textarea>
<button [disabled]="corpusValidationInProgress" type="submit" class="button-level-one">Search</button>
</form>
在处理表单提交的方法中,我访问了 controls NgForm 实例的属性,它在浏览器中工作正常。
onSearchCorpus(formData: NgForm) {
...
const corpusErrors = formData.controls.corpus.errors;
...
}
但是,当我尝试使用 Karma 测试此方法时,NgForm 的 controls
属性为空。我很困惑为什么会这样。该方法失败并出现错误 cannot read property "errors"of undefined
。
我的测试是这样的:
it('should not perform corpusSearch if selected corpus no longer exists', () => {
component.ngOnInit();
const form = fixture.debugElement.query(By.css('form'));
form.triggerEventHandler('submit', null);
...
});
这就是我设置测试服的方式:
beforeEach(async(() => {
TestBed.configureTestingModule({
// schemas: [NO_ERRORS_SCHEMA],
imports: [
FormsModule,
PopoverModule
],
providers: [
CorpusSearchService,
{ provide: ApiService, useValue: ApiServiceStub },
{ provide: Router, useClass: RouterStab },
],
declarations: [
SearchCorpusComponent, //<--component under test
ComboBoxComponent //<-- 3rd party combobox which is used for first control
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SearchCorpusComponent);
component = fixture.componentInstance;
apiService = fixture.debugElement.injector.get(ApiService);
subject = new Subject();
});
那么,为什么controls
在测试环境中是空的呢?
最佳答案
controls
为“空”的原因是在调用 onSearchCorpus
时控件尚未在测试环境中“初始化”。
我准备了一个 Plunkr (请参阅 form.component.spec
文件)演示了此问题。在同一个文件中还有一个可行的解决方案。
简而言之,为了使这项工作正常进行,您需要使用 fakeAsync
机制。
所以代替:
it('testing form the wrong way', () => {
fixture.detectChanges();
comp.onSubmit(); // Validates and submits a form
expect(comp.submitted).toEqual(false);
});
你应该像这样写一个测试:
it('testing form the proper way', fakeAsync(() => {
// This first detectChanges is necessary to properly set up the form
fixture.detectChanges();
// Tick needs to be called in order for form controls to be registered properly.
tick();
comp.onSubmit(); // Validates and submits a form
expect(comp.submitted).toEqual(false);
}));
关于javascript - 为什么 ngForm "controls"属性在我的测试中为空? ( Angular ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46769953/