Appearance
Tester un composant avec des notions asynchrones
Pour tester si une liste d'utilisateurs récupérée avec une requête HTTP s'affiche correctement dans le template d'un composant Angular, vous pouvez suivre les étapes ci-dessous :
- Dans votre composant, créez une propriété users pour stocker la liste d'utilisateurs et une méthode
getUsers()
pour récupérer la liste d'utilisateurs en utilisant une requête HTTP. Par exemple :
ts
import { Component, OnInit, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
standalone: true,
template: `
<h1>Liste des utilisateurs</h1>
<ul>
@for (user of users ; track user.id) {
<li>{{ user.name }}</li>
}
</ul>
`
})
export class AppComponent implements OnInit {
private http = inject(HttpClient);
users: any = [];
ngOnInit() {
this.http.get('https://jsonplaceholder.typicode.com/users')
.subscribe(users => {
this.users = users;
});
}
}
Dans le fichier de test unitaire du composant, importez les modules
HttpClientTestingModule
etHttpTestingController
depuis@angular/common/http/testing
.Dans la méthode
beforeEach()
de votre test unitaire, configurez le module de test en utilisant leHttpClientTestingModule
. Par exemple :
ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let httpMock: HttpTestingController;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ AppComponent, HttpClientTestingModule ]
})
.compileComponents();
httpMock = TestBed.inject(HttpTestingController);
});
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
afterEach(() => {
httpMock.verify()
})
// tests go here
});
httpMock.verify() ?
httpMock.verify()
est une méthode utilisée dans les tests unitaires pour vérifier si toutes les requêtes HTTP programmées avec httpMock ont été effectuées correctement.
Dans la méthode
beforeEach()
, après avoir configuré le module de test et simulé la réponse HTTP, appelez la méthodefixture.detectChanges()
pour mettre à jour le template avec les nouvelles valeurs des variables du composant.Dans la méthode
it()
du test, utilisez la méthodewhenStable()
pour attendre la résolution de toutes les opérations asynchrones avant de vérifier le template. Par exemple :
ts
it('should display a list of users', async () => {
httpMock.expectOne('https://jsonplaceholder.typicode.com/users')
.flush([
{ name: 'Leanne Graham' },
{ name: 'Ervin Howell' },
// etc.
]);
fixture.detectChanges(); // déclenche ngOnInit
await fixture.whenStable(); // Garantit que toutes les opérations asynchrones se sont terminées
fixture.detectChanges(); // Affiche le résultat dans le template
const userElements = fixture.nativeElement.querySelectorAll('li');
expect(userElements.length).toBe(10);
expect(userElements[0].textContent).toBe('Leanne Graham');
expect(userElements[1].textContent).toBe('Ervin Howell');
});
Dans ce code, le test attend la résolution de toutes les opérations asynchrones en appelant la méthode whenStable()
avant de vérifier les éléments du template. Cela garantit que les données récupérées par la requête HTTP sont à jour lorsque le test vérifie les éléments du template.
En utilisant la méthode whenStable()
dans ce test unitaire, vous pouvez être sûr que les données dans le template sont à jour et que le test vérifie la bonne liste d'utilisateurs.
C'est quoi un mock et httpMock ?
Un mock est un objet de substitution utilisé dans les tests unitaires pour simuler le comportement d'un objet réel. Les mocks peuvent être utilisés pour simuler des réponses à des appels de fonction, des retours de valeur ou des événements d'un objet réel, afin de tester le comportement d'une partie de votre code sans avoir à utiliser l'objet réel.
Dans l'exemple de test unitaire, l'objet httpMock
est un mock de l'objet HttpTestingController
qui est utilisé pour simuler une réponse HTTP à une requête faite par le composant. Le mock est utilisé pour vérifier si la requête a été faite et pour simuler une réponse HTTP pour tester le comportement du composant en réponse à cette requête.
Utiliser des mocks dans les tests unitaires est utile pour isoler le code que vous testez et pour éviter les dépendances externes qui pourraient affecter les résultats des tests. Cela permet également de tester des parties spécifiques de votre code de manière plus précise et de détecter les erreurs plus facilement.
Pourquoi utiliser HttpClientTestingModule au lieu de HttpClientModule ?
Dans les tests unitaires, il est recommandé d'utiliser le module HttpClientTestingModule
au lieu du module HttpClientModule
pour les opérations HTTP. Le module HttpClientTestingModule
est conçu pour les tests unitaires et permet de simuler des réponses HTTP dans les tests, ce qui n'est pas possible avec le module HttpClientModule
.
En utilisant le module HttpClientTestingModule
, vous pouvez facilement contrôler les réponses HTTP dans vos tests unitaires et vérifier si votre code gère correctement ces réponses. Cela permet de tester les parties de votre code qui utilisent des requêtes HTTP de manière plus précise et sans avoir à se connecter à un serveur réel.