A text input in a form does not update ngModel in tests
See original GitHub issueI’m submitting a…
[x] Bug report
Current behavior
I test a component containing a form element and a text input element in it. There is a two-way binding between the input element and a text property of a component class via ngModel directive.
The test updates the input’s value, fires dispatchEvent and checks the property of the component. The test fails:
Error: Expected 'Default title' to equal 'Updated Task'.
at stack (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:2338:17)
at buildExpectationResult (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:2308:14)
at Spec.expectationResultFactory (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:858:18)
at Spec.addExpectationResult (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:487:34)
at Expectation.addExpectationResult (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:802:21)
at Expectation.toEqual (http://localhost:9876/base/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?73bc53d3671677e6a093fc74e4f9bcde57e5f7ad:2252:12)
at http://localhost:9876/_karma_webpack_/webpack:/src/app/app.component.spec.ts:35:26
at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:388:1)
at AsyncTestZoneSpec.webpackJsonp../node_modules/zone.js/dist/zone-testing.js.AsyncTestZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:479:1)
at ProxyZoneSpec.webpackJsonp../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:236:1)
NOTE: If I comment out the form element in the app.component.html then the test passes.
Expected behavior
Chrome 64.0.3282 (Windows 7.0.0): Executed 1 of 1 SUCCESS
Minimal reproduction of the problem with instructions
1. Create project:
ng new angular-app
2. Update files:
app.component.html - replace all the text with the following:
<form novalidate (ngSubmit)="onSubmit()">
<input name="title" type="text" [(ngModel)]="title">
</form>
app.component.ts - replace all the text with the following:
import {Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Default title';
onSubmit() {
console.log('title is:' + this.title);
}
}
app.component.spec.ts - replace all the text with the following:
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {FormsModule} from '@angular/forms';
import {AppComponent} from './app.component';
import {By} from "@angular/platform-browser";
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let comp: AppComponent;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent
],
imports: [FormsModule],
}).compileComponents().then(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.debugElement.componentInstance;
})
}));
it('should bind an input to a property (async)', async(() => {
fixture.detectChanges();
// Update the title input
const inputElement = fixture.debugElement.query(By.css('input[name="title"]')).nativeElement;
inputElement.value = 'Updated Task';
inputElement.dispatchEvent(new Event('input'));
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(comp.title).toEqual('Updated Task');
});
}));
});
app.module.ts - replace all the text with the following:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
What is the motivation / use case for changing the behavior?
I need to test a component with a form inside.
3. Run tests:
ng test
Environment
Angular CLI: 1.7.2
Node: 8.5.0
OS: win32 x64
Angular: 5.2.7
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
@angular/cli: 1.7.2
@angular-devkit/build-optimizer: 0.3.2
@angular-devkit/core: 0.3.2
@angular-devkit/schematics: 0.3.2
@ngtools/json-schema: 1.2.0
@ngtools/webpack: 1.10.1
@schematics/angular: 0.3.2
@schematics/package-update: 0.3.2
typescript: 2.5.3
webpack: 3.11.0
Browser:
- [*] Chrome (desktop) version XX
Issue Analytics
- State:
- Created 6 years ago
- Reactions:4
- Comments:5 (1 by maintainers)
This looks like a duplicate of https://github.com/angular/angular/issues/22606.
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.