feat: Introduce comprehensive unit tests for models and BLoCs using mockito and bloc_test, and refine TripBloc error handling.
Some checks failed
Deploy to Play Store / build_and_deploy (push) Has been cancelled
Some checks failed
Deploy to Play Store / build_and_deploy (push) Has been cancelled
This commit is contained in:
103
test/blocs/trip_bloc_test.dart
Normal file
103
test/blocs/trip_bloc_test.dart
Normal file
@@ -0,0 +1,103 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:travel_mate/blocs/trip/trip_bloc.dart';
|
||||
import 'package:travel_mate/blocs/trip/trip_event.dart';
|
||||
import 'package:travel_mate/blocs/trip/trip_state.dart';
|
||||
import 'package:travel_mate/repositories/trip_repository.dart';
|
||||
import 'package:travel_mate/models/trip.dart';
|
||||
|
||||
import 'trip_bloc_test.mocks.dart';
|
||||
|
||||
@GenerateMocks([TripRepository])
|
||||
void main() {
|
||||
group('TripBloc', () {
|
||||
late MockTripRepository mockTripRepository;
|
||||
late TripBloc tripBloc;
|
||||
|
||||
final trip = Trip(
|
||||
id: 'trip1',
|
||||
title: 'Summer Vacation',
|
||||
description: 'Trip to the beach',
|
||||
location: 'Miami',
|
||||
startDate: DateTime(2023, 6, 1),
|
||||
endDate: DateTime(2023, 6, 10),
|
||||
createdBy: 'user1',
|
||||
createdAt: DateTime(2023, 1, 1),
|
||||
updatedAt: DateTime(2023, 1, 2),
|
||||
participants: ['user1'],
|
||||
status: 'active',
|
||||
);
|
||||
|
||||
setUp(() {
|
||||
mockTripRepository = MockTripRepository();
|
||||
tripBloc = TripBloc(mockTripRepository);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
tripBloc.close();
|
||||
});
|
||||
|
||||
test('initial state is TripInitial', () {
|
||||
expect(tripBloc.state, TripInitial());
|
||||
});
|
||||
|
||||
// LoadTripsByUserId
|
||||
blocTest<TripBloc, TripState>(
|
||||
'emits [TripLoading, TripLoaded] when LoadTripsByUserId is added',
|
||||
setUp: () {
|
||||
when(
|
||||
mockTripRepository.getTripsByUserId('user1'),
|
||||
).thenAnswer((_) => Stream.value([trip]));
|
||||
},
|
||||
build: () => tripBloc,
|
||||
act: (bloc) => bloc.add(const LoadTripsByUserId(userId: 'user1')),
|
||||
expect: () => [
|
||||
TripLoading(),
|
||||
TripLoaded([trip]),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<TripBloc, TripState>(
|
||||
'emits [TripLoading, TripError] when stream error',
|
||||
setUp: () {
|
||||
when(
|
||||
mockTripRepository.getTripsByUserId('user1'),
|
||||
).thenAnswer((_) => Stream.error('Error loading trips'));
|
||||
},
|
||||
build: () => tripBloc,
|
||||
act: (bloc) => bloc.add(const LoadTripsByUserId(userId: 'user1')),
|
||||
expect: () => [
|
||||
TripLoading(),
|
||||
const TripError('Impossible de charger les voyages'),
|
||||
],
|
||||
);
|
||||
|
||||
// TripCreateRequested
|
||||
blocTest<TripBloc, TripState>(
|
||||
'emits [TripLoading, TripCreated] when TripCreateRequested is added',
|
||||
setUp: () {
|
||||
when(
|
||||
mockTripRepository.createTrip(any),
|
||||
).thenAnswer((_) async => 'trip1');
|
||||
},
|
||||
build: () => tripBloc,
|
||||
act: (bloc) => bloc.add(TripCreateRequested(trip: trip)),
|
||||
// Note: TripBloc automatically refreshes list if _currentUserId is set.
|
||||
// Here we haven't loaded trips so _currentUserId is null.
|
||||
expect: () => [TripLoading(), const TripCreated(tripId: 'trip1')],
|
||||
);
|
||||
|
||||
// TripDeleteRequested
|
||||
blocTest<TripBloc, TripState>(
|
||||
'emits [TripOperationSuccess] when TripDeleteRequested is added',
|
||||
setUp: () {
|
||||
when(mockTripRepository.deleteTrip('trip1')).thenAnswer((_) async {});
|
||||
},
|
||||
build: () => tripBloc,
|
||||
act: (bloc) => bloc.add(const TripDeleteRequested(tripId: 'trip1')),
|
||||
expect: () => [const TripOperationSuccess('Trip deleted successfully')],
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user