Angular Not Setting Correct Form Validation Classes In Tests
There seems to be an issue with Angular applying validation classes in unit test environment. By validation classes I mean ng-valid
and ng-invalid
. The Angular version I use is 8.2.14
.
Let's take for example this component:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<form ngForm>
<input type="text" required name="firstName" [(ngModel)]="firstName"/>
<button type="submit">Submit</button>
</form>
`
})
export class AppComponent {
firstName = '';
}
The template is a simple template-driven form. If you render it in the browser, before any interaction the input will have the following class name: ng-untouched ng-pristine ng-invalid
. This is exactly what we expect: the input is required, the value is an empty string, therefore it is not valid.
However, if we have the following test case:
import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
FormsModule
],
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should apply the correct validation classes', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
fixture.detectChanges();
fixture.whenStable().then(() => {
console.log(fixture.nativeElement.querySelector('input'));
});
});
});
The logged element will have the class name: ng-untouched ng-pristine ng-valid
. I expect the input to be invalid in the testing browser, just like if it is rendered without the testing config.
My question is why is there such difference in the validation classes and how can I achieve correct validation in the testing environment?
Thanks in advance!
Answer
I think you need to make your it
spec async, because it has some async code inside it.
Also looking at this issue you'd need to use fixture.autoDetectChanges()
or run fixture.detectChanges()
after whenStable
.
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM