Search code examples
flutterflutter-test

How to deal with "Assertion error is not a subtype of of type 'Exception' in type cast


I'm facing a weird error while trying to implement blocTesting in my project when my test is failing. It goes as follows :

Expected: [
            SignUpCreateAccountLoading:SignUpCreateAccountLoading(),
            SignupInitial:SignupInitial()
          ]
  Actual: [
            SignUpCreateAccountLoading:SignUpCreateAccountLoading(),
            SignUpCreateAccountFailure:SignUpCreateAccountFailure(type '_AssertionError' is not a subtype of type 'Exception' in type cast, nikunj@gmail.com),
            SignupInitial:SignupInitial()
          ]

I'm required to use the real apis in bloc testing for this project.

Below are the blocTest, bloc, blocEvent,blocState and repository files.

SignupBlocTest


void main() async {
  group('SignupBloc', () {
    late SignUpBloc signUpBloc;
    setUp(() {
      signUpBloc = SignUpBloc();
    });

    test('initial state of the bloc is [AuthenticationInitial]', () {
      expect(SignUpBloc().state, SignupInitial());
    });

    group('SignUpCreateAccount', () {
      blocTest<SignUpBloc, SignUpState>(
        'emits [SignUpCreateAccountLoading, SignupInitial] '
        'state when successfully Signed up',
        setUp: () {},
        build: () => SignUpBloc(),
        act: (SignUpBloc bloc) => bloc.add(const SignUpCreateAccount(
            'Nevil', 'abcd', 'nikunj@gmail.com', 'english',),),
        wait: const Duration(milliseconds: 10000),
        expect: () => [
          SignUpCreateAccountLoading(),
          SignupInitial(),
        ],
      );
    });
  });
}

signupBloc

class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
  final SignUpRepository _signUpRepository = SignUpRepository();

  SignUpBloc() : super(SignupInitial()) {
    // Register events here
    on<SignUpCreateAccount>(_onSignUpCreateAccount);
  }

  Future<void> _onSignUpCreateAccount(SignUpCreateAccount event, Emitter<SignUpState> emit) async {
    emit(SignUpCreateAccountLoading());
    try {
      final bool _success = await _signUpRepository.createAccount(event.firstName, event.lastName, event.eMailAddress, event.language);

      if (_success) emit(SignUpCreateAccountSuccess());
    } catch (e) {
      emit(SignUpCreateAccountFailure(exception: e.toString(), email: event.eMailAddress));
      emit(SignupInitial());
    }
  }
}

Signup_event

part of 'signup_bloc.dart';

abstract class SignUpEvent extends Equatable {
  const SignUpEvent();

  @override
  List<Object> get props => <Object>[];
}

class SignUpCreateAccount extends SignUpEvent {
  final String firstName;
  final String lastName;
  final String eMailAddress;
  final String language;

  const SignUpCreateAccount(this.firstName, this.lastName, this.eMailAddress, this.language);
  @override
  List<Object> get props => <Object>[firstName, lastName, eMailAddress, language];
}

Signup_state

part of 'signup_bloc.dart';

abstract class SignUpState extends Equatable {
  const SignUpState();

  @override
  List<Object> get props => <Object>[];
}

class SignupInitial extends SignUpState {}

class SignUpCreateAccountLoading extends SignUpState {}

class SignUpCreateAccountSuccess extends SignUpState {}

class SignUpCreateAccountFailure extends SignUpState {
  final String exception;
  final String email;

  const SignUpCreateAccountFailure({required this.exception, required this.email});
  @override
  List<Object> get props => <Object>[exception, email];
}

Signuprepository

class SignUpRepository {
  Future<bool> createAccount(String _firstName, String _lastName, String _eMailAddress, String _language) async {
    final Response _response;
    try {
      _response = await CEApiRequest().post(
        Endpoints.createCustomerAPI,
        jsonData: <String, dynamic>{
          'firstName': _firstName,
          'lastName': _lastName,
          'email': _eMailAddress,
          'language': _language,
          'responseUrl': Endpoints.flutterAddress,
        },
      );

      final Map<String, dynamic> _customerMap = jsonDecode(_response.body);
      final CustomerModel _clients = CustomerModel.fromJson(_customerMap['data']);

      if (_clients.id != null) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      final MYException _exception = e as MYException;
      throw _exception;
    }
  }
}


Solution

  • An _AssertionError is being thrown somewhere, but you are attempting to cast it to an exception in your catch. Instead, you should rethrow the exceptions you are expecting and handle the other types in a different way. Below I return false, but you can choose the appropriate behavior to fit your needs.

    try {
      ...
    } on MYException catch (e) {
      rethrow;
    } catch (e) {
      // Not a MYException so returning false.
      return false;
    }