--- description: "BLoC testing conventions for {{PROJECT_NAME}}" alwaysApply: false --- # BLoC Testing Standards — {{PROJECT_NAME}} ## Test pattern (bloc_test) ```dart // {{TEST_PATTERN}} void main() { late AuthBloc authBloc; late MockAuthRepository mockRepo; setUp(() { mockRepo = MockAuthRepository(); authBloc = AuthBloc(repository: mockRepo); }); tearDown(() => authBloc.close()); group('AuthBloc', () { blocTest( 'emits [Loading, Authenticated] when login succeeds', build: () { when(() => mockRepo.login(any(), any())) .thenAnswer((_) async => const Right(User(id: '1', email: 'test@test.com'))); return authBloc; }, act: (bloc) => bloc.add(const AuthLoginRequested(email: 'test@test.com', password: 'pass')), expect: () => [ const AuthLoading(), isA(), ], ); blocTest( 'emits [Loading, Failure] when login fails', build: () { when(() => mockRepo.login(any(), any())) .thenAnswer((_) async => const Left(AuthError('Invalid credentials'))); return authBloc; }, act: (bloc) => bloc.add(const AuthLoginRequested(email: 'bad', password: 'bad')), expect: () => [ const AuthLoading(), const AuthFailure('Invalid credentials'), ], ); }); } ``` ## Rules - Use `mocktail` for mocking — never `mockito` - Every BLoC test file: `test/features/[feature]/[feature]_bloc_test.dart` - Coverage requirement: all state transitions must be tested - Use `Given/When/Then` naming in test descriptions - Test error paths as thoroughly as success paths