# Tests Unitaires - Progression **Date:** 2026-03-14 **Objectif:** Implémenter tests unitaires pour 64 use cases **Statut:** 🚧 **EN COURS** - Fondations établies --- ## 📊 État Actuel ### Tests Créés et Passants ✅ | Feature | Use Case Testé | Status | Tests | |---------|----------------|--------|-------| | Profile | GetProfile | ✅ PASS | 4/4 tests passés | | Settings | ResetSettings | ✅ PASS | 4/4 tests passés | **Total: 8/8 tests passés (100%)** ### Tests Créés avec Erreurs ❌ | Feature | Use Case | Problème | |---------|----------|----------| | Contributions | GetContributions | Propriétés modèle non concordantes | --- ## 🏗️ Infrastructure de Tests Mise en Place ### 1. Structure de Dossiers ``` test/features/ ├── finance_workflow/domain/usecases/ ├── contributions/domain/usecases/ ├── events/domain/usecases/ ├── members/domain/usecases/ ├── profile/domain/usecases/ ✅ GetProfile tests ├── organizations/domain/usecases/ ├── reports/domain/usecases/ └── settings/domain/usecases/ ✅ ResetSettings tests ``` ### 2. Dépendances de Test (pubspec.yaml) ✅ **Configuré:** - `mockito: ^5.4.4` - Mocking framework - `bloc_test: ^9.1.7` - BLoC testing utilities - `build_runner: ^2.4.13` - Code generation - `flutter_test: sdk` - Flutter testing framework - `integration_test: sdk` - Integration testing ### 3. Build Runner ✅ **Configuré et fonctionnel:** ```bash flutter pub run build_runner build --delete-conflicting-outputs # Succeeded after 27.9s with 18 outputs (38 actions) ``` ### 4. Pattern de Test Établi **Use Case Test Template:** ```dart import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:unionflow_mobile_apps/features/.../domain/repositories/...repository.dart'; import 'package:unionflow_mobile_apps/features/.../domain/usecases/...usecase.dart'; @GenerateMocks([IRepository]) import 'test_name_test.mocks.dart'; void main() { late UseCase useCase; late MockIRepository mockRepository; setUp(() { mockRepository = MockIRepository(); useCase = UseCase(mockRepository); }); group('UseCase Test Group', () { test('should perform expected behavior', () async { // Arrange when(mockRepository.method(...)).thenAnswer((_) async => expectedResult); // Act final result = await useCase(...); // Assert expect(result, equals(expectedResult)); verify(mockRepository.method(...)); verifyNoMoreInteractions(mockRepository); }); }); } ``` --- ## ✅ Tests Réussis - Détails ### GetProfile (4/4 tests ✅) **Fichier:** `test/features/profile/domain/usecases/get_profile_test.dart` **Tests:** 1. ✅ Should return current user profile from repository 2. ✅ Should return null when user is not authenticated 3. ✅ Should throw exception when repository throws 4. ✅ Should cache profile data on successful retrieval **Résultats:** ``` 00:00 +4: All tests passed! ``` **Mock utilisé:** `MockIProfileRepository` **Modèle:** `MembreCompletModel` (3 champs requis: nom, prenom, email) --- ### ResetSettings (4/4 tests ✅) **Fichier:** `test/features/settings/domain/usecases/reset_settings_test.dart` **Tests:** 1. ✅ Should reset configuration to default values 2. ✅ Should handle fallback when reset endpoint fails 3. ✅ Should throw exception when all reset strategies fail 4. ✅ Should return valid config with minimal required fields **Résultats:** ``` 00:00 +4: ResetSettings Use Case - All tests passed! ``` **Mock utilisé:** `MockISystemConfigRepository` **Modèle:** `SystemConfigModel` (tous champs optionnels) --- ## 📋 Prochaines Étapes ### Phase 1: Corriger Tests Existants - [ ] Fixer GetContributions (corriger propriétés modèle) - [ ] Regénérer mocks avec build_runner - [ ] Vérifier 100% tests passants ### Phase 2: Créer Tests pour Features P1 (26 use cases) **Contributions (8 use cases):** - [ ] get_contributions.dart - [ ] get_contribution_by_id.dart - [ ] create_contribution.dart - [ ] update_contribution.dart - [ ] delete_contribution.dart - [ ] pay_contribution.dart - [ ] get_contribution_history.dart - [ ] get_contribution_stats.dart **Events (10 use cases):** - [ ] get_events.dart - [ ] get_event_by_id.dart - [ ] create_event.dart - [ ] update_event.dart - [ ] delete_event.dart - [ ] register_for_event.dart - [ ] cancel_registration.dart - [ ] get_my_registrations.dart - [ ] get_event_participants.dart - [ ] submit_event_feedback.dart **Members (8 use cases):** - [ ] get_members.dart - [ ] get_member_by_id.dart - [ ] create_member.dart - [ ] update_member.dart - [ ] delete_member.dart - [ ] search_members.dart - [ ] export_members.dart - [ ] get_member_stats.dart ### Phase 3: Créer Tests pour Features P2 (18 use cases) **Organizations (7 use cases):** - [ ] get_organizations.dart - [ ] get_organization_by_id.dart - [ ] create_organization.dart - [ ] update_organization.dart - [ ] delete_organization.dart - [ ] get_organization_members.dart - [ ] update_organization_config.dart **Reports (6 use cases):** - [ ] get_reports.dart - [ ] generate_report.dart - [ ] export_report_pdf.dart - [ ] export_report_excel.dart - [ ] schedule_report.dart - [ ] get_scheduled_reports.dart **Settings (5 use cases):** - [x] ✅ reset_settings.dart (4/4 tests) - [ ] get_settings.dart - [ ] update_settings.dart - [ ] get_cache_stats.dart - [ ] clear_cache.dart ### Phase 4: Tests BLoC (10 BLoCs) Pour chaque BLoC, tester: - État initial - Transitions d'états - Gestion d'erreurs - Appels use cases corrects **Utiliser `bloc_test` package:** ```dart blocTest( 'emits [MyState] when event is added', build: () => MyBloc(mockUseCase), act: (bloc) => bloc.add(MyEvent()), expect: () => [MyExpectedState()], ); ``` ### Phase 5: Tests d'Intégration - [ ] Tests end-to-end flows critiques - [ ] Tests avec backend mock complet - [ ] Tests de navigation - [ ] Tests de persistance --- ## 🎯 Objectif Final | Métrique | Cible | Actuel | % | |----------|-------|--------|---| | Use Cases testés | 64 | 2 | 3% | | Tests unitaires | ~256 (4/use case) | 8 | 3% | | BLoCs testés | 10 | 0 | 0% | | Coverage | 80% | ~5% | 6% | --- ## 🔧 Commandes Utiles ### Générer mocks: ```bash flutter pub run build_runner build --delete-conflicting-outputs ``` ### Exécuter tous les tests: ```bash flutter test ``` ### Exécuter tests spécifiques: ```bash flutter test test/features/profile/domain/usecases/ ``` ### Coverage report: ```bash flutter test --coverage genhtml coverage/lcov.info -o coverage/html ``` --- ## 📝 Notes Techniques ### Gotchas Rencontrés 1. **Noms de classes/fichiers incohérents:** - Fichier: `membre_complete_model.dart` - Classe: `MembreCompletModel` (sans 'e' final) - ⚠️ Toujours vérifier le nom exact de la classe 2. **Propriétés de modèles:** - Toujours lire le fichier modèle pour connaître les vraies propriétés - Ne pas inventer de propriétés dans les tests 3. **Génération de mocks:** - Exécuter build_runner après chaque modification de `@GenerateMocks` - Les mocks sont générés dans `*.mocks.dart` 4. **Imports:** - Repository: depuis `domain/repositories/` - Use case: depuis `domain/usecases/` - Modèles: depuis `data/models/` --- **Fondations établies par:** Claude Code **Date:** 2026-03-14 **Statut:** ✅ Infrastructure prête - Prochaine étape: Créer tests pour 62 use cases restants