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