flutter - 错误状态:试图读取在创建其值期间抛出的提供程序
问题描述
问题
我为页面编写小部件测试。它们需要 BLoC 进行渲染。get_it 用于依赖注入。提供程序使用异步函数,因此我创建了一个“假”块,它为小部件测试返回静态数据。
由于某种原因,从 get_it 注入的块不起作用。
我的代码
所以我有一个测试:
void main() {
setUpAll(() async {
SharedPreferences.setMockInitialValues({});
await getIt.reset();
await setup();
getIt.registerFactory(
() => FakeScheduleBloc( // Stack trace says I have an error in this line
getSchedule: getIt(),
getActiveGroup: getIt(),
getGroups: getIt(),
setActiveGroup: getIt(),
getDownloadedSchedules: getIt(),
deleteSchedule: getIt(),
getScheduleSettings: getIt(),
setScheduleSettings: getIt(),
),
);
});
testWidgets('Go to News frome Home', (WidgetTester tester) async {
await tester.pumpWidget(
_getFullContext(const HomeNavigatorScreen(isFirstRun: false)));
await tester.tap(find.byKey(WidgetKeys.bottomBarNews));
await tester.pumpAndSettle();
expect(find.byType(NewsScreen), findsOneWidget);
});
}
上下文构建器:
Widget _getFullContext(Widget child) {
return getAdvancedContext(child, [
BlocProvider<ScheduleBloc>(create: (context) => getIt<FakeScheduleBloc>()), // Stack trace says I have an error in this line
BlocProvider<HomeNavigatorBloc>(
create: (context) => getIt<HomeNavigatorBloc>()),
]);
}
Widget getAdvancedContext(
Widget child, List<BlocProviderSingleChildWidget> providers) {
return MultiBlocProvider(
providers: providers,
child: AdaptiveTheme(
light: lightTheme,
dark: darkTheme,
initial: AdaptiveThemeMode.dark,
builder: (theme, darkTheme) => MaterialApp(
home: child,
),
),
);
}
一个假集团:
// Fake bloc extends real one, but overrides mapEventToState
class FakeScheduleBloc extends ScheduleBloc {
FakeScheduleBloc({
/* some variables */
}) : super(
/* some variables */
);
@override
Stream<ScheduleState> mapEventToState(
ScheduleEvent event,
) async* {
yield SomeStaticData;
}
}
和一个设置:
final getIt = GetIt.instance;
Future<void> setup() async {
// BloC / Cubit
getIt.registerFactory(
() => ScheduleBloc(
// There is an implementation of a real ScheduleBloc
),
);
getIt.registerFactory(() => HomeNavigatorBloc());
}
错误
当我运行测试时,我看到了一些错误。
Error while creating FakeScheduleBloc
Stack trace:
#0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
...
#464 StackZoneSpecification._registerUnaryCallback.<anonymous closure> (package:stack_trace/src/stack_zone_specification.dart)
<asynchronous suspension>
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building MediaQuery(MediaQueryData(size: Size(800.0, 600.0),
devicePixelRatio: 3.0, textScaleFactor: 1.0, platformBrightness: Brightness.light, padding:
EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, alwaysUse24HourFormat:
false, accessibleNavigation: false, highContrast: false, disableAnimations: false, invertColors:
false, boldText: false, navigationMode: traditional)):
GetIt: The compiler could not infer the type. You have to provide a type and optionally a name. Did
you accidentally do `var sl=GetIt.instance();` instead of var sl=GetIt.instance;
'package:get_it/get_it_impl.dart':
Failed assertion: line 333 pos 7: 'type != null || const Object() is! T'
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following StateError was thrown building MediaQuery(MediaQueryData(size: Size(800.0, 600.0),
devicePixelRatio: 3.0, textScaleFactor: 1.0, platformBrightness: Brightness.light, padding:
EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, alwaysUse24HourFormat:
false, accessibleNavigation: false, highContrast: false, disableAnimations: false, invertColors:
false, boldText: false, navigationMode: traditional)):
Bad state: Tried to read a provider that threw during the creation of its value.
The exception occurred during the creation of type ScheduleBloc.
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following message was thrown:
Multiple exceptions (2) were detected during the running of the current test, and at least one was
unexpected.
我的目标
我想创建一个假 bloc 并将其注入 get_it 以测试需要 bloc 的小部件。
为什么我使用 get_it?
我使用它是因为小部件使用 BlocBuilder,这意味着我需要从它继承来创建我的假 bloc。ScheduleBloc 有一个巨大的构造函数,它依赖于同样注入 get_it 的用例,所以我无法摆脱 get_it。
解决方案
推荐阅读
- matlab - Matlab中绘制有向图的问题
- android - 错误:不是封闭类 - MainActivity
- typescript - GraphQLServer 联合类型“抽象类型 N 必须在运行时解析为对象类型”错误
- ignite - 缓存已关闭异常
- python - 不明白 Robot Framework 中这个关键字调用方法
- java - Java,编译器如何知道在这个 lambda 表达式中调用哪个构造函数
- python - 在 tkinter 应用程序开发中,为什么我的代码没有给出任何输出?
- powershell - Robocopy 在 Powershell 脚本中不起作用
- angular - 仅在 jhipster 将 webpack 服务器热重载到浏览器控制台时获取 Angular 错误,而不是在其他编译中
- node.js - 将数据发送到 socket.io 中的特定用户 ID