I have tests like the below:
blocTest(
'emits [ViewData.loading and ViewData.loaded] when GetRepositories is added',
build: () {
when(
() => useCase.getRepositories(),
).thenAnswer((_) async => Right(repositoriesDummyEntityFromRemote));
return homeBloc;
},
act: (HomeBloc bloc) => bloc.add(GetRepositories()),
expect: () => [
HomeState(
statusRepositories: ViewData.loading(message: 'Loading'),
isShowTitle: false,
),
HomeState(
statusRepositories:
ViewData.loaded(data: repositoriesDummyEntityFromRemote),
isShowTitle: false,
),
],
);
When I run get the error:
package:bloc_test/src/bloc_test.dart 229:13 testBloc.<fn>.<fn>
dart:async _completeOnAsyncError
package:bloc_test/src/bloc_test.dart testBloc.<fn>.<fn>
===== asynchronous gap ===========================
dart:async _asyncThenWrapperHelper
package:bloc_test/src/bloc_test.dart testBloc.<fn>.<fn>
dart:async runZonedGuarded
package:bloc_test/src/bloc_test.dart 192:13 testBloc.<fn>
package:bloc_test/src/bloc_test.dart 191:5 testBloc.<fn>
dart:async runZoned
package:bloc/src/bloc_overrides.dart 46:26 BlocOverrides.runZoned
package:bloc_test/src/bloc_test.dart 190:23 testBloc
package:bloc_test/src/bloc_test.dart 156:13 blocTest.<fn>
package:bloc_test/src/bloc_test.dart 155:5 blocTest.<fn>
Expected: [
HomeState:HomeState(Instance of 'ViewData<List<RepositoriesEntity>>', false),
HomeState:HomeState(Instance of 'ViewData<List<RepositoriesEntity>>', false)
]
Actual: [
HomeState:HomeState(Instance of 'ViewData<List<RepositoriesEntity>>', false),
HomeState:HomeState(Instance of 'ViewData<List<RepositoriesEntity>>', false)
]
Which: at location [0] is HomeState:<HomeState(Instance of 'ViewData<List<RepositoriesEntity>>', false)> instead of HomeState:<HomeState(Instance of 'ViewData<List<RepositoriesEntity>>', false)>
WARNING: Please ensure state instances extend Equatable, override == and hashCode, or implement Comparable.
Alternatively, consider using Matchers in the expect of the blocTest rather than concrete state instances.
repositoriesDummyEntityFromRemote
is List<RepositoriesEntity>
Please help me to solve my test. Below is my Bloc, State, and ViewData.
ViewData
class ViewData<T> {
ViewState status;
T? data;
String message = "";
Failure? failure;
ViewData._({
required this.status,
this.data,
this.message = "",
this.failure,
});
factory ViewData.loaded({T? data}) {
return ViewData._(status: ViewState.loaded, data: data);
}
factory ViewData.error({required Failure? failure}) {
return ViewData._(status: ViewState.error, failure: failure);
}
factory ViewData.loading({required String message}) {
return ViewData._(status: ViewState.loading, message: message);
}
factory ViewData.initial() {
return ViewData._(status: ViewState.initial);
}
factory ViewData.empty({required String message}) {
return ViewData._(status: ViewState.empty, message: message);
}
}
HomeState
class HomeState extends Equatable {
final ViewData<List<RepositoriesEntity>> statusRepositories;
final bool isShowTitle;
const HomeState({
required this.statusRepositories,
required this.isShowTitle,
});
HomeState copyWith({
ViewData<List<RepositoriesEntity>>? statusRepositories,
bool? isShowTitle,
}) {
return HomeState(
statusRepositories: statusRepositories ?? this.statusRepositories,
isShowTitle: isShowTitle ?? this.isShowTitle,
);
}
@override
List<Object?> get props => [statusRepositories, isShowTitle];
}
HomeBloc
class HomeBloc extends Bloc<HomeEvent, HomeState> {
final GTHomeUseCase homeUseCase;
HomeBloc({
required this.homeUseCase,
}) : super(HomeState(
statusRepositories: ViewData.initial(),
isShowTitle: false,
)) {
on<GetRepositories>(_getRepositories);
}
Future<void> _getRepositories(
GetRepositories event,
Emitter<HomeState> emit,
) async {
emit(state.copyWith(
statusRepositories: ViewData.loading(message: 'Loading')));
final response = await homeUseCase.getRepositories();
return response.fold(
(Failure failure) => _onFailureRepositories(emit, failure),
(List<RepositoriesEntity> data) => _onSuccessRepositories(emit, data),
);
}
Future<void> _onFailureRepositories(
Emitter<HomeState> emit,
Failure failure,
) async {
emit(state.copyWith(statusRepositories: ViewData.error(failure: failure)));
}
Future<void> _onSuccessRepositories(
Emitter<HomeState> emit,
List<RepositoriesEntity> data,
) async {
emit(state.copyWith(statusRepositories: ViewData.loaded(data: data)));
await Future.delayed(const Duration(milliseconds: 500));
emit(state.copyWith(isShowTitle: true));
}
}
Anyone know how to fix my bloc so I can make it testable?
CodePudding user response:
I think ViewData
and RepositoriesEntity
must extend Equatable, override == and hashCode, or implement Comparable.
If they are not, then there is no way of comparing the states.