Angular 5 template driven form unit Test - Cannot read property 'form' of undefined

Viewed 1450

Hello I'm quite new in testing. I tried a lot to test a function but can't succeed even after reading all Stackoverflow subjects on this. I hope you'll find a way to help me ..

Here is an extract of my html :

<form #myForm="ngForm">

Here is one of my comp:

@ViewChild('myForm')myForm: NgForm;

and I have a validate function :

public valider(): void {
    if (this.myForm.form.valid) {
        //doSomething
    } else {
        console.log('your form is not valid.');
    }
}

Finally here is the test I'm trying to run:

it('should send an error when the form is not valid', () => {
    fixture = TestBed.createComponent(myComponent);
    comp = fixture.componentInstance;
    fixture.detectChanges();
    fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(comp.myForm.form.invalid).toBeTruthy();
        comp.valider();
    });
});

The error I get is:

Unhandled Promise rejection:', 'Cannot read property 'form' of undefined'

Thanks a lot guys

2 Answers

You should initialize your form after the line

 fixture.detectChanges();

like this:

   component.riskForm = new NgForm([],[]);

I have change your component little bit.

import {Component, ViewChild} from '@angular/core';
import {NgForm} from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  @ViewChild('myForm') myForm: NgForm;

  valider = (): boolean => this.myForm.form.valid;
}

And then your tests should looks in this way:

import {TestBed, async, ComponentFixture} from '@angular/core/testing';
import { AppComponent } from './app.component';
import {FormsModule} from '@angular/forms';

describe('AppComponent', () => {

  const initialFormValid = true;
  let fixture: ComponentFixture<AppComponent>;
  let component: AppComponent;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        FormsModule,
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
  });

  it('should be defined', () => {
    expect(component).toBeDefined();
  });

  it('#valider should return forms valid state', () => {
    expect(component.valider()).toEqual(initialFormValid);
  });

});
Related