【问题标题】:How to use get_it (flutter dependency injection) in the widget test?如何在小部件测试中使用 get_it(flutter 依赖注入)?
【发布时间】:2020-10-14 07:56:31
【问题描述】:

当我在项目中使用依赖注入时,我的小部件测试失败。

我的错误如下:

Testing started at 10:07 AM ...
C:\src\flutter\bin\flutter.bat --no-color test --machine --plain-name "Exist FloatingActionButton" test\features\announcement\presentation\widgets_test\announcement_widget_test.dart
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞══════════════════════'═════════════════════════════════════
The following assertion was thrown building _BodyBuilder:
No type AnnouncementBloc is registered inside GetIt.
Did you forget to pass an instance name?
(Did you accidentally do GetIt sl=GetIt.instance(); instead of GetIt sl=GetIt.instance;did you
forget to register it?)
'package:get_it/get_it_impl.dart':
Failed assertion: line 251 pos 14: 'instanceFactory != null'

The relevant error-causing widget was:
Scaffold
file:///C:/Projects/niaz-flutter/lib/features/announcement/presentation/pages/announcements_page.dart:15:12

When the exception was thrown, this was the stack:
#2 _GetItImplementation._findFactoryByNameOrType (package:get_it/get_it_impl.dart:251:14)
#3 _GetItImplementation.get (package:get_it/get_it_impl.dart:263:27)
#4 _GetItImplementation.call (package:get_it/get_it_impl.dart:288:12)
#5 new _AnnouncementsWidgetState (package:niaz/features/announcement/presentation/widgets/announcements_widget.dart:22:19)
#6 AnnouncementsWidget.createState (package:niaz/features/announcement/presentation/widgets/announcements_widget.dart:18:46)
#7 new StatefulElement (package:flutter/src/widgets/framework.dart:4600:25)
#8 StatefulWidget.createElement (package:flutter/src/widgets/framework.dart:896:38)
... Normal element mounting (19 frames)
#27 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3455:14)
#28 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5956:32)
... Normal element mounting (193 frames)
#221 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3455:14)
#222 MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5956:32)
... Normal element mounting (255 frames)
#477 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3455:14)
#478 Element.updateChild (package:flutter/src/widgets/framework.dart:3220:20)
#479 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1132:16)
#480 RenderObjectToWidgetElement.update (package:flutter/src/widgets/binding.dart:1110:5)
#481 RenderObjectToWidgetElement.performRebuild (package:flutter/src/widgets/binding.dart:1124:7)
#482 Element.rebuild (package:flutter/src/widgets/framework.dart:4227:5)
#483 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2632:33)
#484 AutomatedTestWidgetsFlutterBinding.drawFrame (package:flutter_test/src/binding.dart:1016:18)
#485 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:284:5)
#486 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1113:15)
#487 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1052:9)
#488 AutomatedTestWidgetsFlutterBinding.pump. (package:flutter_test/src/binding.dart:889:9)
#491 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:72:41)
#492 AutomatedTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:876:27)
#493 WidgetTester.pumpWidget. (package:flutter_test/src/widget_tester.dart:462:22)
#496 TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:72:41)
#497 WidgetTester.pumpWidget (package:flutter_test/src/widget_tester.dart:459:27)
#498 main. (file:///C:/Projects/niaz-flutter/test/features/announcement/presentation/widgets_test/announcement_widget_test.dart:15:18)
#499 main. (file:///C:/Projects/niaz-flutter/test/features/announcement/presentation/widgets_test/announcement_widget_test.dart:14:45)
#500 testWidgets.. (package:flutter_test/src/widget_tester.dart:144:29)
#511 FakeAsync.flushMicrotasks (package:fake_async/fake_async.dart:192:32)
#512 AutomatedTestWidgetsFlutterBinding.runTest. (package:flutter_test/src/binding.dart:1109:17)
#513 AutomatedTestWidgetsFlutterBinding.runTest. (package:flutter_test/src/binding.dart:1097:35)
(elided 31 frames from class _AssertionError, dart:async, and package:stack_trace)

════════════════════════════════════════════════════════════════════════════════════════════════════

Test failed. See exception logs above.

测试描述为:Exist FloatingActionButton

【问题讨论】:

  • 这是一个非常肮脏和不清楚的问题。请分享您的代码并添加一些标签。

标签: flutter-test


【解决方案1】:

GetIt 中没有注册类型AnnouncementBloc。您是否忘记传递实例名称?

您需要先在测试模式下使用[getIt.registerFactory< AnnouncementBloc >(() => AnnouncementBloc());]

例如,我在我的应用程序中使用了服务定位器模式,并将getIt 那里的所有块和存储库,所以我在serviceLocator 中设置了一个布尔型[testing] 像:

Future<void> serviceLocator({bool testing = false}) async {
    if (testing){
        // unit/widget/bloc test
        getIt.registerFactory<AccountBloc>(() => AccountBloc(accountRepository: getIt()));
        getIt.registerFactory<AccountRepository>(() => AccountRepositoryMock());

    } else {
        // run app
        getIt.registerFactory<AccountBloc>(() => AccountBloc(accountRepository: getIt()));
        getIt.registerFactory<AccountRepository>(() => AccountRepositoryFactory(dioProvider: getIt()));
    }
}

另外,您需要在测试文件中将 [testing] 指定为 true,例如:

void main(){
  serviceLocator(testing: true);

  testWidgets('try widget test', (WidgetTester tester) async {
     .
     .
     .
    });
}

【讨论】:

    【解决方案2】:

    你的问题很不清楚(我想看看你的测试代码),但我想我可以帮助你。

    您可以在setUp()setUpAll() 中设置GetIt.instance 并注册您的模拟BLoC,如下所示:

    class MockMyBloc extends MockBloc<MyStates> implements MyBloc {}
    
    void main() {
    
        MyBloc bloc;
        MockMyBloc mockMyBloc;
       
        setUp(() {
            mockMyBloc = MockMyBloc();
            final dependency_injection = GetIt.instance;
            dependency_injection.registerFactory<MyBloc>(() => mockMyBloc);
    
            bloc = dependency_injection<MyBloc>();
        });
    
        //tests
    }
    

    【讨论】:

      【解决方案3】:

      这取决于您最初在项目中设置get_it 的方式。

      为了解决我的设置问题,我只是在测试文件的setUpAll 方法中调用了注册我的依赖项的方法。

      所以我在 lib 文件夹的根目录中有一个文件来注册我的依赖项:

      final getIt = GetIt.instance;
      
      void setupDependencyInjection() {
        GetIt.instance.registerSingleton<SomeServiceInterface>(SomeService());
      }
       
      

      setupDependencyInjection 方法在 main.dart 文件中的 runApp app 方法之前调用。

      对于测试,您只需在测试文件的 setUpAll 方法中调用相同的方法。

      void main() {
        setUpAll(() {
          setupDependencyInjection();
        });
      
      
        testWidgets('Some test description', (WidgetTester tester) async {
      
          final widget = TestWidget();
      
          await tester.pumpWidget(widget);
        });
      }
      

      【讨论】:

        猜你喜欢
        • 2020-10-25
        • 1970-01-01
        • 1970-01-01
        • 2021-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-19
        • 1970-01-01
        相关资源
        最近更新 更多