2

I have a standard function to register users. In the test file, I am getting the error:

TypeError: this._formBuilder.group is not a function

This seems to be from the ngOnInit function. I have tried importing the testing module numerous ways - as an empty object, etc. It seems as if this is where the problem is coming from. I could try to mock the FormBuilder, but that seems like something that should not be necessary as the function doesn't do any http work.

Typescript File :

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};
};

Test file

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();
    });



});
2
  • The test file is the same as your typescript function. Can you paste the correct test file? Commented Jun 29, 2020 at 2:37
  • Sorry. Fixed it Commented Jun 29, 2020 at 3:01

2 Answers 2

2

In my case, I just replaced:

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

with:

providers: [
        FormBuilder,
      ]
Sign up to request clarification or add additional context in comments.

Comments

0
  1. You can try to remove { provide: FormBuilder, useValue : FormBuilder }, since you have already imported ReactiveFormsModule

2.Try to remove the first beforeEach function and add the fuseConfigServiceSpy as below

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();
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.