我有一个角度组件 - " FooComponent" - 我试图使用Karma / Jasmine进行测试。
以下是foo.component.spec.ts文件中的一些相关代码:
describe('FooComponent', () => {
let component: FooComponent
let fixture: ComponentFixture<FooComponent>
let componentElement: DebugElement
let bar: FormControl
...
beforeEach(() => {
fixture = TestBed.createComponent(FooComponent)
component = fixture.componentInstance
fixture.detectChanges()
component.ngOnInit()
componentElement = fixture.debugElement
bar = component.bar
})
it('should create the FooComponent', () => {
expect(component).toBeTruthy()
})
运行ng test
时出现以下错误:
Chrome 63.0.3239 (Windows 10 0.0.0) FooComponent should create the
FooComponent FAILED
TypeError: Cannot read property 'validate' of undefined
at normalizeValidator .../node_modules/@angular/forms/esm5/forms.js:1059:23)
at Array.map (<anonymous>)
at composeValidators .../node_modules/@angular/forms/esm5/forms.js:2422:1)
at coerceToValidator .../node_modules/@angular/forms/esm5/forms.js:2826:1)
at new FormControl .../node_modules/@angular/forms/esm5/forms.js:3881:1)
at FooComponent.webpackJsonp.../../../../../src/app/foo/foo.component.ts.FooComponent.createFormControls ....../src/app/foo/foo.component.ts:43:16)
at FooComponent.webpackJsonp.../../../../../src/app/foo/foo.component.ts.FooComponent.ngOnInit ....../src/app/foo/foo.component.ts:37:10)
at checkAndUpdateDirectiveInline .../node_modules/@angular/core/esm5/core.js:12400:1)
at checkAndUpdateNodeInline .../node_modules/@angular/core/esm5/core.js:13927:1)
at checkAndUpdateNode .../node_modules/@angular/core/esm5/core.js:13870:1)
如您所见,foo.component.ts的第37行和第43行令人反感:
ngOnInit() {
//the following is line 37
this.createFormControls()
this.createForm()
}
createFormControls() {
//the following is line 43
this.bar = new FormControl('', [Validators.required, this.fooService.validateBar])
}
createForm() {
this.fooForm = new FormGroup({
bar: this.bar
})
}
所以看起来它不喜欢我在FooService中编写的自定义验证函数(我将其注入FooComponent)。这是foo.service.ts中的那个函数:
validateBar(bar: FormControl) {
return bar.value.length == 10 ? null: { invalidBar: true }
}
有什么想法吗?
答案 0 :(得分:0)
我看到你在beforeEach
:
beforeEach(() => {
...
component.ngOnInit()
...
});
您不应该直接调用ngOnInit()
,当您执行此操作时,测试运行程序会调用该方法:
fixture.detectChanges()
您可以参考解释此问题的文档:https://angular.io/guide/testing
答案 1 :(得分:0)
如果有人偶然发现了这一点,“cannot read property 'validate' of undefined”错误可能是最烦人的事情,而且几乎没有答案描述要尝试的内容。
问题是您的 formGroup 未定义,但您的 HTML 正在尝试呈现并检查 formGroup.valid(例如您的表单提交按钮是否已启用)
通常模拟 FormBuilder(),FormGroup,构建可重用组件所需的数据对象,然后将其提供给组件就足够了,一切都很好。但有些时候不是
无论如何.. 尝试添加一个 ngIf 以便在允许呈现组件之前初始化控件
<form class="form-popup" *ngIf="formGroup && formGroup.controls.length" [formGroup]="formGroup">
这通常只有在组件使用可重用组件(用于外观),然后在 ngOnInit 上注入 formGroup 数据时才会出现问题。哇啦啦——
<ng-template *ngComponentOutlet="component;injector:injector"></ng-template
还没有足够的数据,且fixture.detectChanges() 不足以渲染它。