如何在小部件测试中使用get_it(抖动依赖注入)?

时间:2020-06-24 05:56:43

标签: flutter-test

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

我的错误如下:

测试于10:07 AM开始... C:\ src \ flutter \ bin \ flutter.bat-无色测试--machine --plain-name“ Exist FloatingActionButton” test \ features \ announcement \ presentation \ widgets_test \ announcement_widget_test.dart W小工具图书馆的例外情况╞═​​═════════════════════'══════════════════ ═══════════════════ 在构建_BodyBuilder时引发了以下断言: GetIt中没有注册任何类型的AnnouncementBloc。 您是否忘了传递实例名称? (您是否意外地执行GetIt sl = GetIt.instance();而不是GetIt sl = GetIt.instance;是您吗? 忘记注册了吗?) 'package:get_it / get_it_impl.dart': 断言失败:第251行pos 14:'instanceFactory!= null'

相关的引起错误的小部件是: 脚手架 文件:/// C:/Projects/niaz-flutter/lib/features/announcement/presentation/pages/announcements_page.dart:15:12

引发异常时,这是堆栈: #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(软件包:niaz / features / announcement / presentation / widgets / announcements_widget.dart:22:19) #6 AnnouncementsWidget.createState(软件包:niaz / features / announcement / presentation / widgets / announcements_widget.dart:18:46) #7新的StatefulElement(package:flutter / src / widgets / framework.dart:4600:25) #8 StatefulWidget.createElement(package:flutter / src / widgets / framework.dart:896:38) ...普通元件安装(19帧) #27 Element.inflateWidget(包:flutter / src / widgets / framework.dart:3455:14) #28 MultiChildRenderObjectElement.mount(包:flutter / src / widgets / framework.dart:5956:32) ...普通元件安装(193帧) #221 Element.inflateWidget(软件包:flutter / src / widgets / framework.dart:3455:14) #222 MultiChildRenderObjectElement.mount(包:flutter / src / widgets / framework.dart:5956:32) ...普通元件安装(255帧) #477 Element.inflateWidget(软件包:flutter / src / widgets / framework.dart:3455:14) #478 Element.updateChild(package:flutter / src / widgets / framework.dart:3220:20) #479 RenderObjectToWidgetElement._rebuild(包:flutter / src / widgets / binding.dart:1132:16) #480 RenderObjectToWidgetElement.update(package:flutter / src / widgets / binding.dart:1110:5) #481 RenderObjectToWidgetElement.performRebuild(包:flutter / src / widgets / binding.dart:1124:7) #482 Element.rebuild(包:flutter / src / widgets / framework.dart:4227:5) #483 BuildOwner.buildScope(包: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(包:flutter / src / scheduler / binding.dart:1113:15) #487 SchedulerBinding.handleDrawFrame(package:flutter / src / scheduler / binding.dart:1052:9) #488 AutomatedTestWidgetsFlutterBinding.pump。 (包:flutter_test / src / binding.dart:889:9) #491 TestAsyncUtils.guard(软件包:flutter_test / src / test_async_utils.dart:72:41) #492 AutomatedTestWidgetsFlutterBinding.pump(软件包:flutter_test / src / binding.dart:876:27) #493 WidgetTester.pumpWidget。 (软件包:flutter_test / src / widget_tester.dart:462:22) #496 TestAsyncUtils.guard(软件包:flutter_test / src / test_async_utils.dart:72:41) #497 WidgetTester.pumpWidget(软件包:flutter_test / src / widget_tester.dart:459:27) 第498章主(文件:/// C:/Projects/niaz-flutter/test/features/announcement/presentation/widgets_test/announcement_widget_test.dart:15:18) 第499章主(文件:/// 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。 (包:flutter_test / src / binding.dart:1109:17) #513 AutomatedTestWidgetsFlutterBinding.runTest。 (package:flutter_test / src / binding.dart:1097:35) (从_AssertionError类,dart:async和package:stack_trace中删除了31帧)

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

测试失败。请参阅上面的异常日志。 测试描述为:Exist FloatingActionButton

3 个答案:

答案 0 :(得分:2)

这取决于您最初如何在项目中设置 get_it

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

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

final getIt = GetIt.instance;

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

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

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

void main() {
  setUpAll(() {
    setupDependencyInjection();
  });


  testWidgets('Some test description', (WidgetTester tester) async {

    final widget = TestWidget();

    await tester.pumpWidget(widget);
  });
}

答案 1 :(得分:0)

AnnouncementBloc内没有注册类型GetIt。您忘了传递实例名称吗?

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

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

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 :(得分:0)

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

您可以在 GetIt.instancesetUp() 中设置 setUpAll() 并注册您的模拟 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
}