Flutter 颤振块测试未捕获异常
我正试图在我的Flutter应用程序中测试BLoCs,但我遇到了下面这个问题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
===== 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];
}