【问题标题】:Angular Testing error - this._formBuilder.group is not a function角度测试错误 - this._formBuilder.group 不是函数
【发布时间】:2020-10-19 01:38:53
【问题描述】:

我有一个注册用户的标准功能。在测试文件中,我收到错误:

TypeError: this._formBuilder.group is not a function

这似乎来自 ngOnInit 函数。我尝试过多种方式导入测试模块 - 作为空对象等。似乎这就是问题所在。我可以尝试模拟 FormBuilder,但这似乎是不必要的,因为该函数不执行任何 http 工作。

打字稿文件:

import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/internal/operators';

import { FuseConfigService } from '@fuse/services/config.service';
import { fuseAnimations } from '@fuse/animations';

import { AuthService } from 'app/main/services/auth.service';

@Component({
    selector     : 'register',
    templateUrl  : './register.component.html',
    styleUrls    : ['./register.component.scss'],
    encapsulation: ViewEncapsulation.None,
    animations   : fuseAnimations
})
export class RegisterComponent implements OnInit, OnDestroy
{
    registerForm: FormGroup;

    // Private
    private _unsubscribeAll: Subject<any>;

    constructor(
        private _fuseConfigService: FuseConfigService,
        private _formBuilder: FormBuilder,
        public authService: AuthService
    )
    {
        // Configure the layout
        this._fuseConfigService.config = {
            layout: {
                navbar   : {
                    hidden: true
                },
                toolbar  : {
                    hidden: true
                },
                footer   : {
                    hidden: true
                },
                sidepanel: {
                    hidden: true
                }
            }
        };

        // Set the private defaults
        this._unsubscribeAll = new Subject();
    }



    // -----------------------------------------------------------------------------------------------------
    // @ Lifecycle hooks
    // -----------------------------------------------------------------------------------------------------

    /**
     * On init
     */
    ngOnInit(): void
    {
        this.registerForm = this._formBuilder.group({
            name           : ['', Validators.required],
            email          : ['', [Validators.required, Validators.email]],
            password       : ['', Validators.required],
            passwordConfirm: ['', [Validators.required, confirmPasswordValidator]]
        });

        // Update the validity of the 'passwordConfirm' field
        // when the 'password' field changes
        this.registerForm.get('password').valueChanges
            .pipe(takeUntil(this._unsubscribeAll))
            .subscribe(() => {
                this.registerForm.get('passwordConfirm').updateValueAndValidity();
            });
    }

    /**
     * On destroy
     */
    ngOnDestroy(): void
    {
        // Unsubscribe from all subscriptions
        this._unsubscribeAll.next();
        this._unsubscribeAll.complete();
    }
}

/**
 * Confirm password validator
 *
 * @param {AbstractControl} control
 * @returns {ValidationErrors | null}
 */
export const confirmPasswordValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {

    if ( !control.parent || !control )
    {
        return null;
    }

    const password = control.parent.get('password');
    const passwordConfirm = control.parent.get('passwordConfirm');

    if ( !password || !passwordConfirm )
    {
        return null;
    }

    if ( passwordConfirm.value === '' )
    {
        return null;
    }

    if ( password.value === passwordConfirm.value )
    {
        return null;
    }

    return {passwordsNotMatching: true};
};

测试文件

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RegisterComponent } from './register.component';
import { AbstractControl, FormBuilder, FormGroup, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/internal/operators';
import { FuseConfigService } from '@fuse/services/config.service';
import { fuseAnimations } from '@fuse/animations';
import { AuthService } from 'app/main/services/auth.service';
import { ReactiveFormsModule } from '@angular/forms';


import { mockItems } from 'app/main/services/mockItems';

import { MatIconModule } from '@angular/material/icon';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatCheckboxModule } from '@angular/material/checkbox';



describe('RegisterComponent', () => {
    let component: RegisterComponent;
    let fixture: ComponentFixture<RegisterComponent>;


    let MockGroup = new mockItems();







    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [ RegisterComponent ]
        })
        .compileComponents();
    }));




    beforeEach(() => {


        
        TestBed.configureTestingModule({
            imports: [ MatIconModule,
                       MatFormFieldModule,
                       MatCheckboxModule,
                       ReactiveFormsModule ],
            declarations: [ RegisterComponent ],
            providers: [ { provide: FuseConfigService,  useValue : {} },
                         { provide: FormBuilder,        useValue : FormBuilder },
                         { provide: AuthService,        useValue : {} } ]

        });


        fixture = TestBed.createComponent(RegisterComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });




    it('should create', () => {
        expect(component).toBeTruthy();
    });



});

【问题讨论】:

  • 测试文件和你的typescript函数一样。你能粘贴正确的测试文件吗?
  • 对不起。修复它

标签: angular karma-jasmine angular-test angular-unit-test


【解决方案1】:
  1. 您可以尝试删除{ provide: FormBuilder, useValue : FormBuilder },,因为您已经导入了ReactiveFormsModule

2.尝试删除第一个beforeEach函数并添加fuseConfigServiceSpy如下

const fuseConfigServiceSpy = {
    config: {
        layout: {
            navbar: {
                hidden: true
            },
            toolbar: {
                hidden: true
            },
            footer: {
                hidden: true
            },
            sidepanel: {
                hidden: true
            }
        }
    }
};
beforeEach(() => {
    TestBed.configureTestingModule({
        imports: [MatIconModule,
            MatFormFieldModule,
            MatCheckboxModule,
            ReactiveFormsModule],
        declarations: [RegisterComponent],
        providers: [{ provide: FuseConfigService, useValue: fuseConfigServiceSpy },
        { provide: AuthService, useValue: {} }]

    });


    fixture = TestBed.createComponent(RegisterComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
});

【讨论】:

    【解决方案2】:

    就我而言,我只是替换了:

    providers: [
          {provide: FormBuilder, useValue: {FormBuilder}},
      ]
    

    与:

    providers: [
            FormBuilder,
          ]
    

    【讨论】:

      猜你喜欢
      • 2019-07-18
      • 2017-11-19
      • 2020-07-18
      • 1970-01-01
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      相关资源
      最近更新 更多