I have fairly extensive testing in our Angular 2.4 based application. One area we have not been able to test though is forms with inputs. I finally tracked this down to a small test case. I have a plnkr that shows the issue: https://plnkr.co/edit/NyeAoh2Uo5rJT9if6j64 (see form_bug.spec.ts)
Note: I based this example off the way the code in the testing guide works.
The problem is that when we hook an input up with ngModel, and then in the test suite we update the input the data will flow into the component only if the input is not inside a form. If we add it to a form, then the data will not flow correctly.
The core pieces of the code are:
@Component({
selector: 'with-form-test',
template: `
<div>
<div class="show_val">{{testVal}}</div>
<form>
<input name="test_val" id="val_id" [(ngModel)]="testVal" />
</form>
</div>
`,
})
class WithFormTestComp {
testVal: string = 'start';
}
and the test. The two expect() checks in this one fail.
describe('WithFormTest', () => {
let fixture: ComponentFixture<WithFormTestComp>;
let comp: WithFormTestComp;
let comp_de: DebugElement;
function getInput(): DebugElement {
return comp_de.query(By.css('input'));
}
function getShowVal(): DebugElement {
return comp_de.query(By.css('.show_val'));
}
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
FormsModule,
],
declarations: [
WithFormTestComp,
],
});
fixture = TestBed.createComponent(WithFormTestComp);
comp = fixture.componentInstance;
comp_de = fixture.debugElement;
});
it('should update testVal', () => {
fixture.detectChanges();
const input_elt: HTMLInputElement = getInput().nativeElement;
input_elt.value = 'set_val';
input_elt.dispatchEvent(newEvent('input'));
fixture.detectChanges();
const show_val_elt = getShowVal().nativeElement;
expect(comp.testVal).toEqual('set_val');
expect(show_val_elt.textContent).toBe('set_val');
});
});
Does anyone see how to fix this up so that it will work correctly? I have looked around and can't find any bug reports that explain why this would work without the form but fail with it.