---
description: "BLoC testing conventions for TestApp"
alwaysApply: false
---

# BLoC Testing Standards — TestApp

## Test pattern (bloc_test)
```dart
// blocTest<MyCubit, MyState>(description, build: () => MyCubit(), act: (c) => c.method(), expect: () => [MyState()])

void main() {
  late AuthBloc authBloc;
  late MockAuthRepository mockRepo;

  setUp(() {
    mockRepo = MockAuthRepository();
    authBloc = AuthBloc(repository: mockRepo);
  });

  tearDown(() => authBloc.close());

  group('AuthBloc', () {
    blocTest<AuthBloc, AuthState>(
      '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<AuthAuthenticated>(),
      ],
    );

    blocTest<AuthBloc, AuthState>(
      '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
