首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >颤振测试查找器找不到我的有状态小部件

颤振测试查找器找不到我的有状态小部件
EN

Stack Overflow用户
提问于 2022-07-02 06:47:09
回答 1查看 267关注 0票数 0

我正在学习本教程https://docs.flutter.dev/development/ui/interactive#the-parent-widget-manages-the-widgets-state,我在main.dart中有以下内容

代码语言:javascript
复制
void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    Widget statesSection = Container(
        padding: const EdgeInsets.all(32),
        child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: const [StatefulParentWidget()]));
    return MaterialApp(
        title: 'Flutter Layout',
        home: Scaffold(
            appBar: AppBar(title: const Text("Flutter Layout")),
            body: ListView(children: [
              statesSection
            ])));
  }

它在以下测试代码中根本找不到任何东西:

代码语言:javascript
复制
testWidgets('State management tests', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(const MyApp());
    expect(find.byType(StatefulParentWidget), findsOneWidget); // Fails!
    expect(find.text("Inactive"), findsOneWidget); // Fails!
    expect(find.text("Active"), findsNothing); // Fails!
});

测试错误消息:

代码语言:javascript
复制
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: exactly one matching node in the widget tree
  Actual: _WidgetTypeFinder:<zero widgets with type "StatefulParentWidget" (ignoring offstage
widgets)>
   Which: means none were found but one was expected

任何建议和洞察力都将受到赞赏。https://github.com/khteh/flutter

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-02 07:06:35

终稿

将代码更改为:

代码语言:javascript
复制
              // titleSection,
              // buttonsSection,
              // textSection,
              statesSection

考试会通过的

代码语言:javascript
复制
  testWidgets('State management tests', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(const MyApp());
    expect(find.byType(Scaffold), findsOneWidget);
    expect(find.byType(StatefulParentWidget), findsOneWidget);

    expect(find.text("Inactive"), findsOneWidget);
    expect(find.text("Active"), findsNothing);
    //StatefulParentWidget statefulParentWidget = const StatefulParentWidget();
    //tester.state(find.byWidget(statefulParentWidget));
    //expect(find.byWidget(tapboxB), findsOneWidget);
  });

因此,测试只能找到已经呈现的小部件,在您的示例中,statesSection中的小部件曾经脱离了舞台。

以前的讨论

1枚带脚手架

如果您面临以下相同的异常消息:

代码语言:javascript
复制
flutter: (The following exception is now available via WidgetTester.takeException:)
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
flutter: The following assertion was thrown building MainPage:
flutter: No MediaQuery widget ancestor found.
flutter: Scaffold widgets require a MediaQuery widget ancestor.

将您的测试代码更改为此,它应该可以工作。

代码语言:javascript
复制
void main() {
  testWidgets('State management tests', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(MaterialApp(
      home: const MainPage(),
    ));
    expect(find.byType(ParentWidget), findsOneWidget); // Fails!
    expect(find.text("Inactive"), findsOneWidget); // Fails!
    expect(find.text("Active"), findsNothing); // Fails!
  });
}

完整代码在这里:

代码语言:javascript
复制
void main() {
  testWidgets('State management tests', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(MaterialApp(home: const MainPage(),));
    expect(find.byType(ParentWidget), findsOneWidget); // Fails!
    expect(find.text("Inactive"), findsOneWidget); // Fails!
    expect(find.text("Active"), findsNothing); // Fails!
  });
}

class MainPage extends StatelessWidget {
  const MainPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Hello"),
        ),
        body: Container(
            padding: const EdgeInsets.all(32),
            child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: const [ParentWidget()])));
  }
}

// ParentWidget manages the state for TapboxB.

//------------------------ ParentWidget --------------------------------

class ParentWidget extends StatefulWidget {
  const ParentWidget({super.key});

  @override
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      child: TapboxB(
        active: _active,
        onChanged: _handleTapboxChanged,
      ),
    );
  }
}

//------------------------- TapboxB ----------------------------------

class TapboxB extends StatelessWidget {
  const TapboxB({
    super.key,
    this.active = false,
    required this.onChanged,
  });

  final bool active;
  final ValueChanged<bool> onChanged;

  void _handleTap() {
    onChanged(!active);
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        child: Center(
          child: Text(
            active ? 'Active' : 'Inactive',
            style: const TextStyle(fontSize: 32.0, color: Colors.white),
          ),
        ),
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: active ? Colors.lightGreen[700] : Colors.grey[600],
        ),
      ),
    );
  }
}

2无脚手架

如果您只想测试小部件,那么您必须用以下内容替换您的文本小部件:

代码语言:javascript
复制
          child: Text(
            active ? 'Active' : 'Inactive',
            textDirection: TextDirection.ltr,
            style: const TextStyle(fontSize: 32.0, color: Colors.white),
          ),

在我的第一个例子中,Scallfold完成了这个任务,这样您就可以在不告诉textDirection属性的情况下进行测试。请参考TextDirection enum进一步阅读。

完整代码在这里:

代码语言:javascript
复制
void main() {
  testWidgets('State management tests', (WidgetTester tester) async {
    // Build our app and trigger a frame.
    await tester.pumpWidget(statesSection);
    expect(find.byType(ParentWidget), findsOneWidget); // Fails!
    expect(find.text("Inactive"), findsOneWidget); // Fails!
    expect(find.text("Active"), findsNothing); // Fails!
  });
}

Widget statesSection = Container(
    padding: const EdgeInsets.all(32),
    child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: const [ParentWidget()]));

class MainPage extends StatelessWidget {
  const MainPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Hello", textDirection: TextDirection.ltr),
        ),
        body: Container(
            padding: const EdgeInsets.all(32),
            child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: const [ParentWidget()])));
  }
}

// ParentWidget manages the state for TapboxB.

//------------------------ ParentWidget --------------------------------

class ParentWidget extends StatefulWidget {
  const ParentWidget({super.key});

  @override
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
      _active = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      child: TapboxB(
        active: _active,
        onChanged: _handleTapboxChanged,
      ),
    );
  }
}

//------------------------- TapboxB ----------------------------------

class TapboxB extends StatelessWidget {
  const TapboxB({
    super.key,
    this.active = false,
    required this.onChanged,
  });

  final bool active;
  final ValueChanged<bool> onChanged;

  void _handleTap() {
    onChanged(!active);
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        child: Center(
          child: Text(
            active ? 'Active' : 'Inactive',
            textDirection: TextDirection.ltr,
            style: const TextStyle(fontSize: 32.0, color: Colors.white),
          ),
        ),
        width: 200.0,
        height: 200.0,
        decoration: BoxDecoration(
          color: active ? Colors.lightGreen[700] : Colors.grey[600],
        ),
      ),
    );
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72837032

复制
相关文章

相似问题

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