Appearance
Migration des tests unitaires vers Vitest dans Angular
Avec Angular 20, Karma est officiellement déprécié. Il est désormais possible (et conseillé) d'utiliser Vitest — rapide, moderne, compatible Vite et parfaitement adapté aux tests unitaires.
Avantages de Vitest
- Démarrage ultra-rapide des tests
- Compatible nativement avec Vite
- Syntaxe moderne et intuitive
- Support natif de TypeScript
- Interface en ligne de commande claire
- Remplacement officiel de Karma dans Angular
Deux solutions disponibles
Il existe deux approches pour utiliser Vitest avec Angular :
- Solution native (expérimentale, depuis la v20) - Intégrée directement dans Angular
- Solution AnalogJS (recommandée pour le moment) - Plus stable et complète
Solution 1 : Configuration native (expérimentale)
Installation des dépendances
bash
npm install -D vitest jsdom
Configuration dans angular.json
Modifiez la section test
dans votre angular.json
:
json
{
"projects": {
"my-app": {
"architect": {
"test": {
"builder": "@angular/build:unit-test",
"options": {
"tsConfig": "tsconfig.spec.json",
"buildTarget": "::development",
"runner": "vitest",
"providersFile": "src/app/setup.ts"
}
}
}
}
}
}
Fichier de configuration
Créez un fichier src/app/setup.ts
pour configurer l'environnement de test. Ce fichier permet de charger des providers qui seront disponibles dans tous vos tests :
ts
import { provideZonelessChangeDetection } from "@angular/core";
// Configuration pour les tests avec détection de changements zoneless
// Ces providers seront automatiquement chargés dans tous vos tests
export default [provideZonelessChangeDetection()];
Providers globaux
Le fichier setup.ts
est idéal pour configurer des providers qui doivent être disponibles dans tous vos tests, comme les services HTTP, la détection de changements, ou d'autres dépendances globales.
Expérimental
Cette solution native est encore expérimentale dans Angular. Pour une solution plus stable, utilisez la solution AnalogJS.
Utilisez
globals
dans le fichier de configuration de Vitest pour importer les fonctions de test de Vitest dans chaque fichier de test. Voir plus bas.
Solution 2 : Configuration AnalogJS (recommandée)
1. Désinstaller les dépendances inutiles
Si vous avez essayé d'utiliser @analogjs/platform
, retirez-le :
bash
npm rm @analogjs/platform @nx/vite
2. Installer les packages nécessaires
bash
npm i -D @analogjs/vitest-angular vitest @vitest/ui @analogjs/vite-plugin-angular jsdom
3. Mettre à jour angular.json
Remplacez le builder dans la section test
:
json
{
"projects": {
"my-app": {
"architect": {
"test": {
"builder": "@analogjs/vitest-angular:test"
}
}
}
}
}
4. Créer la configuration Vitest
Créez un fichier vite.config.ts
à la racine du projet :
ts
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import angular from '@analogjs/vite-plugin-angular';
export default defineConfig({
plugins: [angular()],
test: {
environment: 'jsdom',
setupFiles: ['src/test.setup.ts'],
globals: true, // Permet d'importer les fonctions de test de Vitest dans chaque fichier de test sans avoir à les importer manuellement dans chaque fichier de test
include: ['src/**/*.spec.ts']
}
});
5. Initialiser l'environnement Angular
Créez un fichier src/test.setup.ts
:
ts
import 'zone.js';
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
getTestBed().initTestEnvironment(
BrowserTestingModule,
platformBrowserTesting()
);
6. Adapter tsconfig.spec.json
Mettez à jour votre tsconfig.spec.json
:
json
{
"compilerOptions": {
"types": ["vitest", "vite/client", "node"]
},
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
],
"files": [
"src/test.setup.ts"
]
}
Lancement des tests
bash
npm test
Créer des tests avec Vitest
La création des tests reste similaire à Jasmine, mais avec la syntaxe de Vitest. Important : vous devez importer les fonctions de test de Vitest dans chaque fichier de test :
ts
import { TestBed } from '@angular/core/testing';
import { UserService } from './user.service';
import { describe, it, expect, beforeEach, vi } from 'vitest';
describe('UserService', () => {
let service: UserService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(UserService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('should return users', () => {
// Utilisation de vi.fn() pour créer des espions
const mockUsers = [
{ id: 1, name: 'John Doe', username: 'johndoe', email: '[email protected]' }
];
const spy = vi.fn().mockReturnValue(mockUsers);
service.getUsers = spy;
const result = service.getUsers();
expect(result).toEqual(mockUsers);
expect(spy).toHaveBeenCalled();
});
});