Description
I'm using freezed for most of my classes and when trying to test them via bloc_test I get the following error:
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.
Among other error messages indicating that the objects are not equal. At first I thought the issue was with bloc_test not picking up the == override properly, but as I stepped through the code I noticed that trying to compare two objects with == return false, while converting those same objects to JSON and comparing them with == returns true
I believe I'm using the class as intended and will put snippets below.
Steps To Reproduce
I can't share exact code but I'll try to re-create structure. These steps also include full bloc_test steps but you may be able to create 2 Bloc/Cubit States with freezed and compare to reproduce.
2. Create abstract class that is used as general state in cubit with corresponding immutable subclasses generated with freezed
part of 'scanner_cubit.dart';
abstract class ScannerStates {}
@freezed
abstract class InitialScannerState extends ScannerStates with _$InitialScannerState {
const factory InitialScannerState(
{required final ScannerSelection selection,
@Default([]) final List rows,
@Default(0) final int currentLayer,
@Default(0.0) final double screenWidth,
@Default(0.0) final double screenHeight,
@Default(0.0) final double devicePixelRatio,
@Default(false) final bool showCursor}) = _InitialScannerState;
...
3. run the builder to generate freezed files/classes: `flutter packages pub run build_runner build`
4. Create cubit with basic functionality and state manipulation that emits new state (one of subclasses mentioned above)
5. Create blocTest and expect updated state with specified values that will be changed upon calling a function (can use `verify` and convert to strings to test equality as well. `expectedState can be replace with actual state or defined above in `verify`)
build...
act.... (emit state)
expect: () => [expectedState] // Throws errors/fails test
verify: (cubit) => {
...
print(cubit.state == expectedState); // return false and fails test
print((cubit.state).toString() == expectedState.toString()); // Returns true and test succeeds
6. Run test and see error
**Expected Behavior**
2 states of the same type with same values to return `true` when compared with `==`
**Screenshots**
N/A
**Additional Context**
Additional logs:
Description I'm using freezed for most of my classes and when trying to test them via bloc_test I get the following error:
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.
Among other error messages indicating that the objects are not equal. At first I thought the issue was with bloc_test not picking up the==
override properly, but as I stepped through the code I noticed that trying to compare two objects with==
return false, while converting those same objects to JSON and comparing them with==
returns true I believe I'm using the class as intended and will put snippets below.Steps To Reproduce I can't share exact code but I'll try to re-create structure. These steps also include full bloc_test steps but you may be able to create 2 Bloc/Cubit States with freezed and compare to reproduce.
dependencies: flutter: sdk: flutter freezed_annotation: ^2.0.1 json_annotation: ^4.5.0 flutter_dotenv: ^5.0.2 bloc: ^8.0.3 flutter_bloc: ^8.0.1 bloc_test: ^9.0.3 mocktail: ^0.3.0 dev_dependencies: flutter_test: sdk: flutter
flutter_lints: ^1.0.4 build_runner: ^2.1.10 freezed: ^2.0.3 json_serializable: ^6.0.0 ffigen: ^6.0.0
part of 'scanner_cubit.dart';
abstract class ScannerStates {} @freezed abstract class InitialScannerState extends ScannerStates with _$InitialScannerState { const factory InitialScannerState( {required final ScannerSelection selection, @Default([]) final List rows,
@Default(0) final int currentLayer,
@Default(0.0) final double screenWidth,
@Default(0.0) final double screenHeight,
@Default(0.0) final double devicePixelRatio,
@Default(false) final bool showCursor}) = _InitialScannerState;
...
build... act.... (emit state) expect: () => [expectedState] // Throws errors/fails test verify: (cubit) => { ... print(cubit.state == expectedState); // return false and fails test print((cubit.state).toString() == expectedState.toString()); // Returns true and test succeeds
testBloc..
package:bloc_test/src/bloc_test.dart:229
dart:async _completeOnAsyncError
package:bloc_test/src/bloc_test.dart testBloc..
package:bloc_test/src/bloc_test.dart:1
===== asynchronous gap ===========================
dart:async _asyncThenWrapperHelper
package:bloc_test/src/bloc_test.dart testBloc..
package:bloc_test/src/bloc_test.dart:1
dart:async runZonedGuarded
testBloc.
package:bloc_test/src/bloc_test.dart:192
testBloc.
package:bloc_test/src/bloc_test.dart:191
dart:async runZoned
BlocOverrides.runZoned
package:bloc/src/bloc_overrides.dart:46
testBloc
package:bloc_test/src/bloc_test.dart:190
blocTest.
package:bloc_test/src/bloc_test.dart:156
blocTest.
package:bloc_test/src/bloc_test.dart:155