【问题标题】:Why doesn't my Angular test like my custom form validation function?为什么我的 Angular 测试不像我的自定义表单验证功能?
【发布时间】:2018-07-11 07:06:36
【问题描述】:

我有一个角度组件 - “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 }
}

有什么想法吗?

【问题讨论】:

    标签: javascript angular typescript jasmine karma-runner


    【解决方案1】:

    我看到你的 beforeEach 中有这个:

    beforeEach(() => {
        ...
        component.ngOnInit()
        ...
    });
    

    您不应直接调用ngOnInit(),当您执行此操作时,测试运行程序会调用该方法:

    fixture.detectChanges()
    

    您可以参考解释此问题的文档:https://angular.io/guide/testing

    【讨论】:

      【解决方案2】:

      如果有人偶然发现这一点,“无法读取未定义的属性'验证'”错误可能是最令人讨厌的发现,并且几乎没有描述尝试什么的答案。

      问题是您的 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() 还不够渲染。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-14
        • 2017-02-16
        • 2021-04-21
        • 2021-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多