首页 > 解决方案 > 错误状态:试图读取在创建其值期间抛出的提供程序

问题描述

问题

我为页面编写小部件测试。它们需要 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。

标签: flutterdartbloc

解决方案


推荐阅读