You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Description
I am trying to implement Reso Coder's Clean Architecture in my own project and have come across this problem while testing. Using the when method from Mocktail would throw out the error: type 'Null' is not a subtype of type 'Future<Either<Failure, List<WorkoutEntity>>>'. A minimal reproduction will be given below.
I've confirmed it's not a bloc_test issue as the last test still does not pass.
Steps To Reproduce
flutter create bug
Copy and paste the following 'pubspec.yaml' file:
pubspec.yaml
name: bug
description: A new Flutter project.
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
# Functional programming
dartz: ^0.10.0-nullsafety.2
# BLoC (State management)
flutter_bloc: ^7.1.0
# Boilerplate code
equatable: ^2.0.3
dev_dependencies:
flutter_test:
sdk: flutter
# Testing for BLoC
bloc_test: ^8.1.0
# Mock testing
mocktail: ^0.1.4
# The following section is specific to Flutter.
flutter:
uses-material-design: true
Copy and paste the following file into the 'test' directory:
Copy and paste the following files into the 'lib' directory:
failures.dart
import 'package:equatable/equatable.dart';
abstract class Failure extends Equatable {
@override
List<Object?> get props => [];
}
class ReadFailure extends Failure {}
i_workout_repository.dart
import 'package:dartz/dartz.dart';
import 'failures.dart';
import 'workout_entity.dart';
abstract class IWorkoutRepository {
/// Gets all [WorkoutEntity] from the database.
///
/// Returns [List<WorkoutEntity>].
Future<Either<Failure, List<WorkoutEntity>>> getAllWorkoutEntities();
}
use_case.dart
import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import 'failures.dart';
import 'i_workout_repository.dart';
import 'workout_entity.dart';
// Parameters have to be put into a container object so that they can be
// included in this abstract base class method definition.
abstract class UseCase<Type, Params> {
Future<Either<Failure, Type>> call(Params params);
}
class NoParams extends Equatable {
@override
List<Object> get props => [];
}
class GetAllWorkouts implements UseCase<List<WorkoutEntity>, NoParams> {
final IWorkoutRepository repository;
const GetAllWorkouts(this.repository);
@override
Future<Either<Failure, List<WorkoutEntity>>> call(NoParams params) async {
return await repository.getAllWorkoutEntities();
}
}
workout_entity.dart
import 'package:equatable/equatable.dart';
class WorkoutEntity extends Equatable {
@override
List<Object?> get props => [];
}
workouts_bloc.dart
import 'package:flutter_bloc/flutter_bloc.dart';
import 'use_case.dart';
import 'workouts_event.dart';
import 'workouts_state.dart';
const String WORKOUT_LOAD_FAILURE_MESSAGE =
'Workouts failed to load. Are there new fields present in [WorkoutEntity]?';
class WorkoutsBloc extends Bloc<WorkoutsEvent, WorkoutsState> {
final GetAllWorkouts getAllWorkouts;
WorkoutsBloc({
required this.getAllWorkouts,
}) : super(WorkoutsLoadInProgress());
@override
Stream<WorkoutsState> mapEventToState(
WorkoutsEvent event,
) async* {
if (event is WorkoutsLoaded) {
yield* _mapWorkoutsLoadedToState();
}
}
Stream<WorkoutsState> _mapWorkoutsLoadedToState() async* {
final workoutsEither = await getAllWorkouts(NoParams());
yield workoutsEither.fold(
(failure) => WorkoutsLoadFailed(message: WORKOUT_LOAD_FAILURE_MESSAGE),
(workouts) => WorkoutsLoadSuccess(workouts: workouts),
);
}
}
workouts_events.dart
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
@immutable
abstract class WorkoutsEvent extends Equatable {
const WorkoutsEvent();
@override
List<Object> get props => [];
}
/// Load all workouts.
class WorkoutsLoaded extends WorkoutsEvent {}
workouts_state.dart
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import 'workout_entity.dart';
@immutable
abstract class WorkoutsState extends Equatable {
const WorkoutsState();
@override
List<Object> get props => [];
}
class WorkoutsLoadInProgress extends WorkoutsState {}
class WorkoutsLoadSuccess extends WorkoutsState {
final List<WorkoutEntity> workouts;
const WorkoutsLoadSuccess({required this.workouts});
@override
List<Object> get props => [workouts];
@override
String toString() => 'WorkoutsLoaded { workouts: $workouts }';
}
class WorkoutsLoadFailed extends WorkoutsState {
final String message;
const WorkoutsLoadFailed({required this.message});
@override
List<Object> get props => [message];
}
flutter test
See errors
Expected Behavior
Expected: Mocked function correctly outputs.
Actual: Tests cannot proceed due to the type Null... error.
The text was updated successfully, but these errors were encountered:
Description
I am trying to implement Reso Coder's Clean Architecture in my own project and have come across this problem while testing. Using the
when
method from Mocktail would throw out the error:type 'Null' is not a subtype of type 'Future<Either<Failure, List<WorkoutEntity>>>'
. A minimal reproduction will be given below.I've confirmed it's not a
bloc_test
issue as the last test still does not pass.Steps To Reproduce
flutter create bug
pubspec.yaml
workouts_bloc_test.dart
failures.dart
i_workout_repository.dart
use_case.dart
workout_entity.dart
workouts_bloc.dart
workouts_events.dart
workouts_state.dart
flutter test
Expected Behavior
Expected: Mocked function correctly outputs.
Actual: Tests cannot proceed due to the
type Null...
error.The text was updated successfully, but these errors were encountered: