1

I am trying to test the input boxes in angular 4 using the angular testing framework. However, I can't get the value of the input box inside a form. Referring to the angular testing docs, I could see that I need to fire some sort of Input event, however, there is not much explanation and I can't get the test working.

How can I tell angular to detect the changes that I am making to the model so as to verify them in the test spec? The input value in the test spec is always blank - an empty string. I just want to figure out the reason why this fails.

The code for the view :

//template-driven-form.component.html
<form  #myForm="ngForm" (ngSubmit)='onSubmit()'>

  <div>
    <Label for="name">Hero Name </Label>
    <input required type="text" id="name" name = 'name' [(ngModel)]='heroes[currentHero].name' #name='ngModel' #nameSpy>
  </div>
  <div>
    <Label for="alter-ego">Alter Ego </Label>
    <input type="text" id="alter-ego" name="alterEgo" [(ngModel)]="heroes[currentHero].alterEgo" #alterEgo="ngModel" #alterEgoSpy>
  </div>
  <div>
    <Label for="powers">Power</Label>
    <select name="powers" id="powers"  [(ngModel)]="heroes[currentHero].power" #power="ngModel" #powerSpy>
      <option *ngFor="let power of powers" >{{power}}</option></select>
  </div>
  <div><button type='submit' [disabled]='!myForm.form.valid'>submit</button></div>

</form>

The backing component:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'template-driven-form',
  templateUrl: 'template-driven-form.component.html',
  styleUrls: ['./template-driven-form.component.css'],
  moduleId: module.id
})
export class TemplateDrivenFormComponent implements OnInit {

  heroes: any = [{ name: 'Superman', alterEgo: 'crypton-man', power: 'fly' },
    { name: 'Batman', alterEgo: 'earth-man', power: 'Batmobile' }];
  currentHero: number = 0;

  powers = ['run', 'fly', 'jump', 'surf', 'Batmobile', 'cry']

  constructor() { }

  ngOnInit() { }

  onSubmit() {
    alert("you just submitted the form!");
  }

}

The test case :

import { TestBed, ComponentFixture, async } from '@angular/core/testing';
import {DebugElement} from '@angular/core';
import {By} from '@angular/platform-browser';
import {TemplateDrivenFormComponent} from './template-driven-form.component';

import { FormsModule, NgForm } from '@angular/forms';
//import { RouterTestingModule } from '@angular/router/testing';



describe('Template Driven Form Component should ', () => {

  let page: Page;

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

  beforeEach(() => {
    page = new Page(TestBed.createComponent(TemplateDrivenFormComponent));
  });

  it(' bind the values to the input components ', () => {
    page.fixture.detectChanges();

    page.component.heroes = [{ name: 'A', alterEgo: 'B', power: 'cry' }];

    page.alterEgoInput.dispatchEvent(new Event('input'));


    page.fixture.detectChanges();

    expect(page.alterEgoInput.value).toBe('A');
    expect(page.nameInput.value).toBe('B');
    expect(page.powerInput.value).toBe('cry');


  });

});



class Page {
  nameInput: any;
  alterEgoInput: any;
  powerInput: any;

  component: TemplateDrivenFormComponent;
  debugElement: DebugElement;


  constructor(public fixture: ComponentFixture<TemplateDrivenFormComponent>) {
    let inputs = fixture.debugElement.queryAll(By.css('input'));
    this.nameInput = inputs[0].nativeElement;
    this.alterEgoInput = inputs[1].nativeElement;
    this.powerInput = fixture.debugElement.query(By.css('select')).nativeElement;
    this.component = fixture.componentInstance;
  }
}
basum
  • 319
  • 1
  • 3
  • 18

0 Answers0