Reputation: 1397
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();
});
});
Upvotes: 2
Views: 4495
Reputation: 2928
In my case, I just replaced:
providers: [
{provide: FormBuilder, useValue: {FormBuilder}},
]
with:
providers: [
FormBuilder,
]
Upvotes: 2
Reputation: 1549
{ 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();
});
Upvotes: 0