我正在为我的小部件编写一些Flutter 测试,有很多似乎不必要的代码,但我不知道如何在没有它的情况下运行测试.

我需要测试自定义小部件的状态.我有一个现有的GlobalKey来执行此操作;因此,我需要使用testWidgets而不是test进行测试.

以下是我第一次try 的内容:

await tester.pumpWidget(
     MyTextField(
          key: myFieldKey,
     ),
);

这导致了以下错误:

No Material widget found.
TextField widgets require a Material widget ancestor within the closest LookupBoundary.
In Material Design, most widgets are conceptually "printed" on a sheet of material. In
Flutter's material library, that material is represented by the Material widget. It is
the Material widget that renders ink splashes, for instance. Because of this, many
material library widgets require that there be a Material widget in the tree above them.
To introduce a Material widget, you can either directly include one, or use a widget
that contains Material itself, such as a Card, Dialog, Drawer, or Scaffold.

我加了一个Scaffold:

await tester.pumpWidget(
     Scaffold(
          body: MyTextField(
               key: myFieldKey,
          ),
     ),
);

这给了我这个错误:

No Directionality widget found.
Scaffold widgets require a Directionality widget ancestor.
...
Typically, the Directionality widget is introduced by the MaterialApp or WidgetsApp
widget at the top of your application widget tree...

所以,我加了一个MaterialApp:

await tester.pumpWidget(
     MaterialApp(
          home: Scaffold(
               body: MyTextField(
                    key: myFieldKey,
               ),
          ),
     ),
);

这招奏效了!问题是,我基本上每次测试都要构建一个新的应用程序.我正在编写几十个测试,所有这些测试都需要像这样进行泵送;这会导致大量额外的代码,而且似乎效率很低.有什么办法可以让我的第一次try 奏效吗?这似乎是最简单、最直观的.

推荐答案

Flutter 需要所有这些额外的 struct 才能发挥作用.您的GlobalKey和定制小部件依赖于上下文才能工作;然而,如果没有MaterialAppScaffold,就没有上下文.

更巧妙地处理这一问题的一种方法是将小部件提取到它自己的方法中.它看起来就像这样:

Future<void> pumpMyTextField(
  WidgetTester tester,
  GlobalKey key,
) async {
  await tester.pumpWidget(
    MaterialApp(
      home: Scaffold(
        body: MyTextField(
          key: key,
        ),
      ),
    ),
  );
}

这可以在您的所有测试中调用,如下所示:

await pumpMyTextField(tester, myFieldKey);

这将使您的所有测试更加清晰,因为"样板"代码被提取出来,并且只编写一次.

Flutter相关问答推荐

Cupertino Buttino SheetAction on按下可触发加载指示器,然后勾选并延迟

我可以在iOS设备上使用Ffltter实现Google Pay按钮吗?

我怎样才能判断一个字符串值是否为空(&Q;&Q;)?

将目标平台设置为Flutter 构建

出现异常.RangeError(RangeError(index):无效值:有效值范围为空:0).分度误差

如何将Visual Studio代码中Flutter 应用的包名从com.example.XXX更改为Play Store中受限制的包名称

Ffmpeg_kit_fltter:^6.0.3版权问题

导航回上一页会将我带回Ffltter应用程序中的登录页面

如何在Flutter 中使用选定的键和值从 map 列表创建 map

Flutter中pubspec.yaml文件中的name参数是什么?

Flutter居中的SizedBox无法居中

网页浏览器不支持鼠标滚动的行项目

如何使用Riverpod提供程序正确构建搜索栏?

在 Flutter 中更改喜欢按钮的 colored颜色

Flutter 中的 Provider 不会在第一次构建 App 时返回

Flutter ImagePicker - 在 onPressed 中异步获取图像显示 lint 警告

Flutter url_launcher 插件抛出java.lang.IllegalArgumentException:接收器未注册:io.flutter.plugins.urllauncher.WebViewActivity

有没有办法在没有收缩包装的情况下在列中使用 ListView.Builder?

使用 Riverpod 和 copyWith 方法更新数据类中列表中变量的值

如何在 ElevatedButton 上设置背景 colored颜色 动画?