Angular 试图在组件中对基于模板的表单进行单元测试,表单没有控件

Angular 试图在组件中对基于模板的表单进行单元测试,表单没有控件,angular,forms,unit-testing,Angular,Forms,Unit Testing,我试图在我的组件中对基于模板的表单进行单元测试。表单很简单,包含个人的联系信息。我试图做的是对各种验证场景进行单元测试。我想我能做的就是简单地设置一个值,比如email address,然后检查ngForm对象,获取emailAddress的相应formControl,然后检查有效性状态。然而,我发现表单虽然存在,但它根本不包含任何控件。因此,似乎该形状从未完全构建 代码(为了简洁起见,我省略了import和一些provider语句等): 个人详细信息联系人信息.component.html

我试图在我的组件中对基于模板的表单进行单元测试。表单很简单,包含个人的联系信息。我试图做的是对各种验证场景进行单元测试。我想我能做的就是简单地设置一个值,比如email address,然后检查ngForm对象,获取emailAddress的相应formControl,然后检查有效性状态。然而,我发现表单虽然存在,但它根本不包含任何控件。因此,似乎该形状从未完全构建

代码(为了简洁起见,我省略了import和一些provider语句等):

个人详细信息联系人信息.component.html


人员详细信息联系信息.component.ts

@组件({
选择器:“人员详细信息联系人信息”,
templateUrl:“个人详细信息联系人信息.component.html”,
视图提供程序:[{provide:ControlContainer,useExisting:NgForm}]
})
导出类PersonDetailsContactInfo组件{
@输入('模型')
型号:{
电子邮件地址:“”,
电话:'',
传真:''
}
}
**单元测试代码**

@组件({
模板:`
`,
提供者:[]
})
导出类TestHostComponent{
模型:PersondetailsContactInfo模型=新的PersondetailsContactInfo模型();
@ViewChild('表单')
ngForm:ngForm;
}
description('在文件“person details contact info.component.ts”中,()=>{
let夹具:组件夹具;
let组件:TestHostComponent;
在每个之前(()=>{
TestBed.configureTestingModule({
导入:[FormsModule,NoopAnimationsModule],
声明:[TestHostComponent,PersonDetailsContactInfo],
提供者:[]
});
fixture=TestBed.createComponent(TestHostComponent);
组件=fixture.componentInstance;
});
它('is具有无效的电子邮件格式',()=>{
component.model.emailAddress='无效的电子邮件格式';
fixture.detectChanges();
const ctrl=component.ngForm.form.get('emailAddress');
expect(ctrl.valid).toBe(false);
});
});
上面的测试是错误的,因为“ctrl”对象为空。表单中不存在emailAddress控件。顺便说一句,这在实际组件中都可以正常工作,所以很明显我在单元测试设置中出了问题


最后,为了理解代码,我的应用程序是这样的,我已经将一个非常大的表单分解成不同的组件“组件是更大形式的一部分。这就是为什么我要绑定到一个模型,并在person-details-contact-info.component的providers部分提供一个现有的NgForm。同样,应用程序本身的一切工作都非常完美,只是我尝试进行单元测试的方式没有达到我预期的效果。

好的,我知道发生了什么。我试图做的事情会起作用,但在单元测试的“it”块中,在“fixture.detectChanges()”之后,我需要做一个“fixture.whenStable()”。例如:

it('is has invalid email format', () => {
    component.model.emailAddress = 'an invalid email format.';
    fixture.detectChanges();

    fixture.whenStable().then(() => {
        const ctrl = component.ngForm.form.get('emailAddress');
        expect(ctrl.valid).toBe(false);
    });        
});
这很有趣,因为我在实际应用程序中遇到了类似的问题,其中一个组件显然不“稳定”。尝试立即访问表单中的formControls(在OnInit或AfterViewInit中)将导致空对象