Flutter小部件测试:无法使用find.byWidget()找到小部件

b4wnujal  于 2022-11-25  发布在  Flutter
关注(0)|答案(2)|浏览(237)

我按照此示例测试视图中是否存在**CircularProgressIndicator**,但即使Flutter构建树显示存在该小部件,我仍不断收到以下异常:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
  Actual: _WidgetFinder:<zero widgets with the given widget
(CircularProgressIndicator(<indeterminate>)) (ignoring offstage widgets)>
   Which: means none were found but one was expected

When the exception was thrown, this was the stack:
#4      main.<anonymous closure> (file:///D:/xxxx/xxxx/xxxx/test/widget_test/widget_test.dart:173:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

This was caught by the test expectation on the following line:
  file:///D:/xxxx/xxxx/xxxx/test/widget_test/widget_test.dart line 173
The test description was:
  ViewRequest: Waiting Types List
════════════════════════════════════════════════════════════════════════════════════════════════════

编辑

我创建了一个方法,它只使用一个**CircularProgressIndicatorWidget作为MaterialApp的“子对象”来构建MaterialApp**:

Widget createMockViewRequest() {
  return MaterialApp(
      title: 'SmartDevice Simulator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const CircularProgressIndicator());
}

以下测试仍然失败,并出现相同的异常:

testWidgets('ViewRequest: Waiting Types List', (WidgetTester tester) async {
  const childWidget = CircularProgressIndicator();

  // Build our app and trigger a frame.
  await tester.pumpWidget(createMockViewRequest());

  // Verify that the page is loading until we receive the types.
  expect(find.byWidget(childWidget), findsOneWidget);

  await tester.pumpAndSettle();
});

我做错了什么吗?也许**MaterialApp**不算容器?但在这种情况下,我不明白为什么它不应该。

wa7juj8i

wa7juj8i1#

为了使它工作,有一些事情要改变。
首先,如果您在测试具有无限动画(如CircularProgressIndicator)的小部件时使用await tester.pumpAndSettle(),测试将失败,因为它正在等待最后一帧更新,但动画从未结束,因此引发超时。
除此之外,您的测试之所以失败是因为您使用的是finder,您试图在UI中找到提供给expect的完全相同的示例,但事实并非如此,因为在UI中构建的示例与您在测试中创建的示例不同,在本例中,如果您想检查UI上是否有CircularProgressIndicator,您应该使用find.byType查找器,它在已构建的小部件中搜索所提供类型的小部件。

63lcw9qa

63lcw9qa2#

你必须像这样改变你的例子:

Widget createMockViewRequest(Widget widget) {
    return MaterialApp(
      title: 'SmartDevice Simulator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: widget,
    );
  }

  testWidgets('ViewRequest: Waiting Types List', (WidgetTester tester) async {
    const childWidget = CircularProgressIndicator();

    // Build our app and trigger a frame.
    await tester.pumpWidget(createMockViewRequest(childWidget));

    // Verify that the page is loading until we receive the types.
    expect(find.byWidget(childWidget), findsOneWidget);
  });

或类似于:

Widget createMockViewRequest() {
    return MaterialApp(
      title: 'SmartDevice Simulator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const CircularProgressIndicator(),
    );
  }

  testWidgets('ViewRequest: Waiting Types List', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(createMockViewRequest());

    // Verify that the page is loading until we receive the types.
    expect(find.byType(CircularProgressIndicator), findsOneWidget);
  });

请注意,我删除了await tester.pumpAndSettle();,因为它会在页面上的动画完成时等待,但CircularProgressIndicator将旋转到无穷大,因此您将遇到超时异常。

相关问题