在提供者的消费者小部件内部的测试中找不到小部件

Posted

技术标签:

【中文标题】在提供者的消费者小部件内部的测试中找不到小部件【英文标题】:Cannot find Widgets in test inside of Consumer Widget of Provider 【发布时间】:2020-08-09 21:54:15 【问题描述】:

我为我的小部件创建了以下 Flutter 测试

testWidgets("", (WidgetTester tester) async 
      await tester.pumpWidget(
        ChangeNotifierProvider<SettingsViewProvider>(
          create: (context) => SettingsViewProvider(),
          child: MaterialApp(
            localizationsDelegates: [S.delegate],
            home: SettingsScreen(),
          ),
        ),
      );

      final textFormFieldFinder = find.byElementType(TextFormField);
      await tester.pump();
      expect(textFormFieldFinder, findsNWidgets(3));
    );

这个小部件是一个有状态的小部件,它使用一个 ChangeNotifierProvider 并且消费者围绕着一个由三个“TextFormFields”组成的列表。

Consumer<State>(
   builder: (context, value, child)=> Column(
       children: [TextFormField(...), TextFormField(...), TextFormField(...)];
   )
)

预期:小部件树中恰好有 3 个匹配节点

实际:_ElementTypeFinder:

Which:表示没有找到,但有一些是预期的

很遗憾,我收到在小部件树中未找到小部件的消息。

【问题讨论】:

问题可能出在您的消费者和提供者之间。尝试执行debugDumpApp 看看会发生什么 我添加了debugDumpApp 结果包含三个TextFormFields Line 117 - Provider Line 121 - TextFormField No.1 Line 165 - TextFormField No.2 Line 213 - TextFormField No.3 1drv.ms/t/s!AvXUDvgUDO2xiodjesQ8j8kwB_LQzQ?e=vr0GHS跨度> 【参考方案1】:

如前所述,您应该使用find.byType,它旨在搜索小部件,而不是find.byElementType,它处理元素。

Flutter 有 3 个 UI 构建块:

Widgets(不可变)-> Elements(可变)-> Render Objects -- 它们不是相互继承的,它们是具有不同用途的不同类型的对象。

TextFormField 是一个Widget,而它被传递给find.byElementType,它需要Element 的祖先

【讨论】:

【参考方案2】:

似乎可以通过以下方式解决:

final textFormFieldFinder = find.byType(TextFormField);

代替:

final textFormFieldFinder = find.byElementType(TextFormField);

【讨论】:

以上是关于在提供者的消费者小部件内部的测试中找不到小部件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 4.2 模拟器中添加小部件?

使用 Android 小部件

Dart/flutter 小部件测试,无论是按键还是文本都找不到文本小部件

在此小部件上方找不到正确的提供程序

缺少发布健康详细信息和发布健康概览小部件

找不到小部件键颤动测试