首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义小部件测试需要材料部件来测试。

自定义小部件测试需要材料部件来测试。
EN

Stack Overflow用户
提问于 2021-05-24 12:35:00
回答 3查看 1.1K关注 0票数 2

我正在尝试在颤振中执行基本的部件测试。基本上,我希望有一个包含数据列表的列表,并在一个自定义小部件(BasicListItem)中显示每个项目,其中也包含一个ListTile小部件。

根小部件:

代码语言:javascript
复制
class MyApp extends StatelessWidget {
  final List taskList = ['List-1', 'List-2', 'List-3'];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        body: ListView.builder(
            itemCount: taskList.length, itemBuilder: _itemBuilder),
      ),
    );
  }

  Widget _itemBuilder(BuildContext context, int index) {
    final String item = taskList[index];
    return BasicListItem(key: Key(item), title: item);
  }
}

列表项小部件(BasicListItem)有一个标题,并在ListTile小部件中使用它。

代码语言:javascript
复制
class BasicListItem extends StatelessWidget {
  final String title;

  const BasicListItem({required Key key, required this.title})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListTile(
      leading: Icon(Icons.map),
      title: Text(title),
    );
  }
}

这是对它的考验:

代码语言:javascript
复制
testWidgets('has title and Icons', (WidgetTester tester) async {

  const testKey = Key('my-key-1');
  const testTitle = 'Demo title';

  await tester.pumpWidget(BasicListItem(key: testKey, title: testTitle));

  expect(find.text(testTitle), findsOneWidget);
});

但是测试会抛出一个错误:

没有找到材料小部件。ListTile小部件需要一个物质小部件祖先。

... ...

运行测试抛出以下TestFailure对象:

预期:小部件树中正好有一个匹配节点:带有文本“演示标题”的_TextFinder:)

但是,如果我在构建方法中将ListTile封装在MaterialApp中,那么测试会通过MaterialApp传递MaterialApp。就像这样:

代码语言:javascript
复制
@override
Widget build(BuildContext context) {
  return MaterialApp(
    title: title,
    home: Scaffold(
      body: ListTile(
        leading: Icon(Icons.map),
        title: Text(title),
      ),
    )
  );
}

但是这样做,我不能在ListView小部件中使用它。此外,我还希望有模块化/独立的定制小部件,这样我也可以在不同的地方使用它。我是新来的,也许我错过了什么。如何构建自定义小部件并对其进行测试?你能帮帮我吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-05-24 12:48:57

ListTile组件来自颤振UI组件的Material部分&它不是一个独立的小部件,因此它需要一个MaterialApp作为父部件。

您可以在这里检查ListTile是否在材料库中:https://api.flutter.dev/flutter/material/ListTile-class.html

此外,您还可以创建多个自定义Widgets,以便在单独的模块中使用,

唯一的要求是在应用程序初始化的一开始就使用MaterialApp

代码语言:javascript
复制
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    /// Only this needs to be a MaterialApp
    return MaterialApp(
      title: 'Welcome to Flutter',

      /// this point to different screen widget also, like MainScreen()
      /// Or you can start using Scaffold from here as well.
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: Text('Hello World'),
        ),
      ),
    );
  }
}

没有必要在您构建的每个自定义小部件上使用MaterialApp作为父部件。只要根也可以。

但是,如果您使用一个小部件来测试,它需要一个Material祖先,您也可以简单地将这个小部件封装在一个Material小部件中。

票数 1
EN

Stack Overflow用户

发布于 2021-05-25 12:42:17

一开始我不理解达山的回答,因为我认为他提供的代码让我直接将MaterialApp和MaterialApp实现为BasicListItem小部件类build ,而不仅仅是在测试套件上实现它。但这给了我实施它的线索。

所以,这是最后的测试用例。我确实用MaterialApp包装了BasicListItem和物料小部件,但没有在构建方法中包装,而是只在测试用例中包装了它们:

代码语言:javascript
复制
testWidgets('has title and Icons', (WidgetTester tester) async {

  const testKey = Key('my-key-1');
  const testTitle = 'Demo title';

  await await tester.pumpWidget(MaterialApp(
    home: Material(
      child: BasicListItem(key: testKey, title: testTitle),
    ),
  ));;

  expect(find.text(testTitle), findsOneWidget);
});

我希望这也能帮助像我这样的人。

票数 2
EN

Stack Overflow用户

发布于 2021-10-26 22:06:36

好吧,这并不是在“颤栗文档”中特别提到的,而是到处都在暗示。在颤振测试端,我们正在抽取一个根小部件来呈现一个框架,就像我们的调色板用来测试小部件一样。

转换为您需要创建一个Root来包装测试中的小部件。易趣的黄金工具包提供的钩子,使这通过pumpWidgetBuilder,这是一个扩展的Widget。

有关更多信息,请访问我的博客,https://fredgrott.medium.com

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67672177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档