Flutter 颤振块测试未捕获异常

Flutter 颤振块测试未捕获异常,flutter,dart,testing,bloc,webexception,Flutter,Dart,Testing,Bloc,Webexception,我正试图在我的Flutter应用程序中测试BLoCs,但我遇到了下面这个问题 ===== asynchronous gap =========================== dart:async _AsyncAwaitCompleter.completeError package:bloc_test/src/bloc_test.dart runBloc

我正试图在我的Flutter应用程序中测试BLoCs,但我遇到了下面这个问题

===== asynchronous gap ===========================
dart:async                                                 _AsyncAwaitCompleter.completeError
package:bloc_test/src/bloc_test.dart                       runBlocTest.<fn>
dart:async                                                 runZoned
package:bloc_test/src/bloc_test.dart 157:9                 runBlocTest
package:bloc_test/src/bloc_test.dart 127:11                blocTest.<fn>

Expected: [
            ChangePasswordLoading:ChangePasswordLoading,
            ChangePasswordFailure:ChangePasswordFailure
          ]
  Actual: [
            ChangePasswordLoading:ChangePasswordLoading,
            ChangePasswordSuccess:ChangePasswordSuccess
          ]
   Which: at location [1] is ChangePasswordSuccess:<ChangePasswordSuccess> instead of ChangePasswordFailure:<ChangePasswordFailure>

package:test_api                             expect
package:bloc_test/src/bloc_test.dart 176:9   runBlocTest.<fn>
===== asynchronous gap ===========================
dart:async                                   _asyncThenWrapperHelper
package:bloc_test/src/bloc_test.dart         runBlocTest.<fn>
dart:async                                   runZoned
package:bloc_test/src/bloc_test.dart 157:9   runBlocTest
package:bloc_test/src/bloc_test.dart 127:11  blocTest.<fn>
====异步间隙===========================
dart:async\u AsyncAwaitCompleter.completeError
包:bloc_test/src/bloc_test.dart runBlocTest。
dart:异步运行分区
包:bloc_test/src/bloc_test.dart 157:9 runBlocTest
包:bloc_test/src/bloc_test.dart 127:11 blocTest。
预期:[
ChangePasswordLoading:ChangePasswordLoading,
ChangePasswordFailure:ChangePasswordFailure
]
实际:[
ChangePasswordLoading:ChangePasswordLoading,
ChangePasswordSuccess:ChangePasswordSuccess
]
其中:在位置[1]处是ChangePasswordSuccess:而不是ChangePasswordFailure:
包:test_api expect
包:bloc_test/src/bloc_test.dart 176:9 runBlocTest。
======异步间隙===========================
dart:async\u asyncThenWrapperHelper
包:bloc_test/src/bloc_test.dart runBlocTest。
dart:异步运行分区
包:bloc_test/src/bloc_test.dart 157:9 runBlocTest
包:bloc_test/src/bloc_test.dart 127:11 blocTest。
这是由于集团测试失败造成的

blocTest<ChangePasswordBloc, ChangePasswordState>(
      'emits [ChangePasswordLoading, ChangePasswordFailure] on failed ChangePassword',
      build: () {
        when(authenticationRepository.changePassword(
          'token',
          'oldPassword',
          'newPassword',
          'newPasswordConfirm',
        )).thenThrow(WebException(403));
        return changePasswordBloc;
      },
      act: (bloc) => bloc
        ..add(ChangePassword(
          oldPassword: 'oldPassword',
          newPassword: 'newPassword',
          newPasswordConfirm: 'newPasswordConfirm',
        )),
      expect: [
        ChangePasswordLoading(),
        ChangePasswordFailure(error: 'Old password is not correct'),
      ],
      errors: [isA<WebException>()],
    );
blocTest(
'在失败的ChangePassword上发出[ChangePasswordLoading,ChangePasswordFailure],
构建:(){
何时(authenticationRepository.changePassword(
“代币”,
“旧密码”,
“新密码”,
“newPasswordConfirm”,
)).然后抛出(WebException(403));
返回changePasswordBloc;
},
法案:(集团)=>集团
…添加(更改密码)(
oldPassword:“oldPassword”,
新密码:“新密码”,
newPasswordConfirm:'newPasswordConfirm',
)),
期望:[
ChangePasswordLoading(),
ChangePasswordFailure(错误:“旧密码不正确”),
],
错误:[isA()],
);
这是我用来测试ChangePasswordBloc的代码(注意所有其他测试都成功通过了)

import'package:bloc_test/bloc_test.dart';
导入“包:flatter_app/business_logic/blocs/change_password/change_password_bloc.dart”;
导入“包:flatter_app/business_logic/blocs/change_password/change_password_event.dart”;
导入“包:flatter_app/business_logic/blocs/change_password/change_password_state.dart”;
导入“包:flatter_app/data/exceptions/web_exception.dart”;
导入“包:flatter_app/data/repositories/authentication_repository.dart”;
进口“包装:颤振安全存储/颤振安全存储.dart”;
进口“包装:颤振试验/颤振试验.dart”;
导入“package:mockito/mockito.dart”;
类MockAuthenticationRepository扩展了Mock
实现AuthenticationRepository{}
类MockSecureStorage扩展了Mock SecureStorage{}
main(){
ChangePasswordBloc ChangePasswordBloc;
MockSecureStorage安全存储;
MockAuthenticationRepository authenticationRepository;
设置((){
secureStorage=MockSecureStorage();
authenticationRepository=MockAuthenticationRepository();
changePasswordBloc=changePasswordBloc(
authenticationRepository,
安全存储,
);
});
拆卸(){
changePasswordBloc?.close();
});
试验(
'初始状态为ChangePasswordInitial',
()=>expect(changePasswordBloc.state,ChangePasswordInitial()),
);
组('ChangePassword process',(){
臃肿的(
'在成功更改密码时发出[ChangePasswordLoading,ChangePasswordSuccess],
构建:(){
何时(authenticationRepository.changePassword(
“代币”,
“旧密码”,
“新密码”,
“newPasswordConfirm”,
)).thenAnswer(()async=>null);
返回changePasswordBloc;
},
法案:(集团)=>集团
…添加(更改密码)(
oldPassword:“oldPassword”,
新密码:“新密码”,
newPasswordConfirm:'newPasswordConfirm',
)),
期望:[
ChangePasswordLoading(),
ChangePasswordSuccess(),
],
);
臃肿的(
'在失败的ChangePassword上发出[ChangePasswordLoading,ChangePasswordFailure],
构建:(){
何时(authenticationRepository.changePassword(
“代币”,
“旧密码”,
“新密码”,
“newPasswordConfirm”,
)).然后抛出(WebException(403));
返回changePasswordBloc;
},
法案:(集团)=>集团
…添加(更改密码)(
oldPassword:“oldPassword”,
新密码:“新密码”,
newPasswordConfirm:'newPasswordConfirm',
)),
期望:[
ChangePasswordLoading(),
ChangePasswordFailure(错误:“旧密码不正确”),
],
错误:[isA()],
);
});
}
这是我的ChangePasswordBloc代码

ChangePasswordBloc

import 'dart:async';
import 'package:flutter_app/data/exceptions/web_exception.dart';
import 'package:flutter_app/data/repositories/authentication_repository.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:bloc/bloc.dart';
import 'change_password_event.dart';
import 'change_password_state.dart';

class ChangePasswordBloc
    extends Bloc<ChangePasswordEvent, ChangePasswordState> {
  final AuthenticationRepository _authenticationRepository;
  final FlutterSecureStorage _secureStorage;

  ChangePasswordBloc(AuthenticationRepository authenticationRepository,
      FlutterSecureStorage secureStorage)
      : _authenticationRepository = authenticationRepository,
        _secureStorage = secureStorage,
        super(ChangePasswordInitial());

  @override
  Stream<ChangePasswordState> mapEventToState(
    ChangePasswordEvent event,
  ) async* {
    if (event is ChangePassword) {
      yield* _mapChangePasswordToState(event);
    }
  }

  Stream<ChangePasswordState> _mapChangePasswordToState(
      ChangePassword event) async* {
    yield ChangePasswordLoading();
    try {
      final accessToken = await _secureStorage.read(key: 'accessToken');

      await _authenticationRepository.changePassword(
        accessToken,
        event.oldPassword,
        event.newPassword,
        event.newPasswordConfirm,
      );
      yield ChangePasswordSuccess();
    } on WebException catch (e) {
      String errorMessage;
      if (e.statusCode == 422) {
        errorMessage = 'Password must be 8 characters long';
      } else if (e.statusCode == 419) {
        errorMessage = 'New Password is not matching';
      } else if (e.statusCode == 403) {
        errorMessage = 'Old password is not correct';
      }
      yield ChangePasswordFailure(error: errorMessage ?? e.toString());
    } catch (err) {
      yield ChangePasswordFailure(
          error: err.toString() ?? 'An unknown error occurred');
    }
  }
}
导入'dart:async';
导入“包:flatter_app/data/exceptions/web_exception.dart”;
导入“包:flatter_app/data/repositories/authentication_repository.dart”;
进口“包装:颤振安全存储/颤振安全存储.dart”;
导入“包:bloc/bloc.dart”;
导入'change_password_event.dart';
导入'change_password_state.dart';
类ChangePasswordBloc
扩展集团{
最终认证存储库\u认证存储库;
最终安全存储_安全存储;
ChangePasswordBloc(AuthenticationRepository AuthenticationRepository,
安全存储(安全存储)
:_authenticationRepository=authenticationRepository,
_secureStorage=secureStorage,
super(ChangePasswordInitial());
@凌驾
流映射事件状态(
ChangePasswordEvent事件,
)异步*{
如果(偶数)
import 'dart:async';
import 'package:flutter_app/data/exceptions/web_exception.dart';
import 'package:flutter_app/data/repositories/authentication_repository.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:bloc/bloc.dart';
import 'change_password_event.dart';
import 'change_password_state.dart';

class ChangePasswordBloc
    extends Bloc<ChangePasswordEvent, ChangePasswordState> {
  final AuthenticationRepository _authenticationRepository;
  final FlutterSecureStorage _secureStorage;

  ChangePasswordBloc(AuthenticationRepository authenticationRepository,
      FlutterSecureStorage secureStorage)
      : _authenticationRepository = authenticationRepository,
        _secureStorage = secureStorage,
        super(ChangePasswordInitial());

  @override
  Stream<ChangePasswordState> mapEventToState(
    ChangePasswordEvent event,
  ) async* {
    if (event is ChangePassword) {
      yield* _mapChangePasswordToState(event);
    }
  }

  Stream<ChangePasswordState> _mapChangePasswordToState(
      ChangePassword event) async* {
    yield ChangePasswordLoading();
    try {
      final accessToken = await _secureStorage.read(key: 'accessToken');

      await _authenticationRepository.changePassword(
        accessToken,
        event.oldPassword,
        event.newPassword,
        event.newPasswordConfirm,
      );
      yield ChangePasswordSuccess();
    } on WebException catch (e) {
      String errorMessage;
      if (e.statusCode == 422) {
        errorMessage = 'Password must be 8 characters long';
      } else if (e.statusCode == 419) {
        errorMessage = 'New Password is not matching';
      } else if (e.statusCode == 403) {
        errorMessage = 'Old password is not correct';
      }
      yield ChangePasswordFailure(error: errorMessage ?? e.toString());
    } catch (err) {
      yield ChangePasswordFailure(
          error: err.toString() ?? 'An unknown error occurred');
    }
  }
}
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';

abstract class ChangePasswordEvent extends Equatable {
  @override
  List<Object> get props => [];
}

class ChangePassword extends ChangePasswordEvent {
  final String oldPassword;
  final String newPassword;
  final String newPasswordConfirm;

  ChangePassword({
    @required this.oldPassword,
    @required this.newPassword,
    @required this.newPasswordConfirm,
  });

  @override
  List<Object> get props => [oldPassword, newPassword, newPasswordConfirm];
}
import 'package:meta/meta.dart';
import 'package:equatable/equatable.dart';

abstract class ChangePasswordState extends Equatable {
  @override
  List<Object> get props => [];
}

class ChangePasswordInitial extends ChangePasswordState {}

class ChangePasswordLoading extends ChangePasswordState {}

class ChangePasswordSuccess extends ChangePasswordState {}

class ChangePasswordFailure extends ChangePasswordState {
  final String error;

  ChangePasswordFailure({@required this.error});

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