Home > Software engineering >  Angular unit test custom validator Cannot read properties of undefined (reading 'dobLengthValid
Angular unit test custom validator Cannot read properties of undefined (reading 'dobLengthValid

Time:03-22

I am trying to test a customer validator but I keep getting this error 'Cannot read properties of undefined (reading 'dobLengthValidator')' I have been researching this but nothing seems to work. The validator checks if years in work is longer than date of birth, and if it is then it displays an error message. Also getting this error 'Error: Unexpected value 'DecoratorFactory' imported by the module 'DynamicTestModule'. Please add an @NgModule annotation.' Code bellow.

Spec file

import { Component, NgModule, Pipe } from '@angular/core';
import {TestBed, ComponentFixture} from '@angular/core/testing';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';

import {FormValidationService} from './form-validation.service';

fdescribe('FormValidationService', () => {
  
  
  let service;
  //let componentInstance: FormValidationService;
  beforeEach(async () =>  {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        ReactiveFormsModule,
        Component,
        Pipe
      ],
      providers: [
        FormBuilder
      ],
      declarations: [FormValidationService]
    }).compileComponents();
    
    service = TestBed.inject(FormValidationService);
    //componentInstance = service.componentInstance;
  });
  it('should be created', () => {
    expect(service).toBeTruthy();
  });
  it('check the validation for years in employment', () => {
    const dobLengthValidator = service.dobLengthValidator
    console.log(dobLengthValidator)
    const birthDate = new Date().setFullYear(1992, 6, 26).toString()
    expect(dobLengthValidator(birthDate, '3', '0')).toBeFalsy()
    expect(dobLengthValidator(birthDate, '40', '0')).toBeTruthy()
  })

});

Component file

import {Injectable} from '@angular/core';
import {AbstractControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';
import { CalculateStartDate } from '@app/utils';
import {environment} from '@environments/environment';
import { isBefore, isValid, subYears } from 'date-fns';
import { from } from 'rxjs';
import { Address } from '../models';

@Injectable({
  providedIn: 'root'
})
export class FormValidationService {


  dobLengthValidator = (dob: string, yrsFieldName: string, monthFieldName: string): ValidatorFn => {
    return (form: FormGroup) : ValidationErrors | null => {
      const yrs: string = !!yrsFieldName ? form.get(yrsFieldName)?.value ?? '0' : '0';
      const mths: string = !!monthFieldName ? form.get(monthFieldName)?.value ?? '0' : '0';
      const timeAliveTimestamp = new Date(dob).getTime();
      const timeEnteredTimestamp = new Date(CalculateStartDate(yrs, mths)).getTime();

      return timeAliveTimestamp >= timeEnteredTimestamp ? {dobLengthValidator: true} : null;
    }
  }

}

CodePudding user response:

You should register the FormValidationService in providers section.

beforeEach(() =>  {
  TestBed.configureTestingModule({
    imports: [
      RouterTestingModule,
      ReactiveFormsModule,
      Component,
      Pipe
    ],
    providers: [
      FormBuilder,
      FormValidationService
    ]
  }).compileComponents();
   
  service = TestBed.inject(FormValidationService);
  //componentInstance = service.componentInstance;
});

References

Angular TestBed

CodePudding user response:

You are overcomplicating the test setup.

Since FormValidationService is just a class without dependencies you can skip the use of the TestBed altogether and just do something like this.

fdescribe('FormValidationService', () => {
  let service: FormValidationService;
  
  beforeEach(() =>  {
    service = new FormValidationService();
  });

  ...

});

In this case since the class doesn't have internal state, you could even remove the beforeEach and just initialize the class once using const service = new FormValidationService();

Cheers

  • Related