Ad

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!

Ad

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.

Ad
source: stackoverflow.com
Ad