Appearance
Comment tester un formulaire ngModel ?
Voici un composant:
ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-signup',
imports: [FormsModule],
standalone: true,
template: `
<form action="#">
<div>
<label for="email" class="label">Votre email</label>
<input type="email" name="email" [(ngModel)]="email" id="email" class="input" placeholder="[email protected]" required="">
</div>
<button type="submit" class="button">Créer le compte</button>
</form>
`
})
export class SignupComponent {
email: string = ''
}
Le test unitaire serait alors le suivant:
ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { SignupComponent } from './signup.component';
describe('MonComposantComponent', () => {
let component: SignupComponent;
let fixture: ComponentFixture<SignupComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [SignupComponent, FormsModule]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(SignupComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
// test la propriété email après avoir rempli le champ email
it('should have email property', async () => {
const emailInput = fixture.nativeElement.querySelector('input[type="email"]');
emailInput.value = '[email protected]'
emailInput.dispatchEvent(new Event('input'));
await fixture.whenStable()
fixture.detectChanges()
expect(component.email).toBe(emailInput.value)
})
});
emailInput.dispatchEvent(new Event('input'))
simule un événement "input" sur l'élément emailInput. Cela permet de déclencher toutes les mécaniques liées à la modification de la valeur d'un champ dans le formulaire, telles que la mise à jour de la propriétéemail
liée à ce champ via[(ngModel)]="email"
.await fixture.whenStable()
attend que tous les observables liés à l'application soient résolus avant de continuer à exécuter le reste du code. Cela garantit que toutes les mises à jour liées à la modification de la valeur du champ email ont été effectuées avant de tester la valeur de la propriétéemail
.
TIP
ngModel
est asynchrone
fixture.detectChanges()
déclenche une nouvelle itération de détection de modifications dans l'application. Cela permet de prendre en compte les modifications apportées à la propriété email
lors de la simulation de l'événement "input" sur l'élément emailInput
.
Tester
Le composant:
ts
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-signup',
standalone: true,
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="signupForm" (ngSubmit)="onSubmit()">
<div>
<label for="email" class="label">Votre email</label>
<input type="email" name="email" formControlName="email" id="email" class="input" placeholder="[email protected]" required="">
</div>
<button type="submit" class="button">Créer le compte</button>
</form>
`
})
export class SignupComponent {
signupForm = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email])
});
onSubmit() {
console.log(this.signupForm.value);
}
}
et le test unitaire:
ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { SignupComponent } from './signup.component';
describe('SignupComponent', () => {
let component: SignupComponent;
let fixture: ComponentFixture<SignupComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [SignupComponent, FormsModule, ReactiveFormsModule]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(SignupComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('form should be invalid', () => {
expect(component.signupForm.valid).toBeFalsy();
});
it('email field validity', () => {
let email = component.signupForm.controls['email'];
expect(email.valid).toBeFalsy();
email.setValue("test");
expect(email.hasError('email')).toBeTruthy();
email.setValue("[email protected]");
expect(email.valid).toBeTruthy();
});
});