1

我正在尝试为我的应用程序中的 DropdownButton 编写小部件测试。我注意到,在点击按钮将其打开后,调用find.byType(DropdownMenuItem)返回的 DropdownMenuItems 数量是预期数量的两倍。

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

enum MyColor {
  blue,
  green,
  red,
  yellow,
  black,
  pink
}

Future<void> main() async {
//   runApp(MyApp());
  
  // tests
  group('dropdown tests', () {
    testWidgets('how many elements should be found?', (tester) async {
      await tester.pumpWidget(MyApp());
      await tester.pumpAndSettle();
      
      expect(find.byType(DropdownButton<MyColor>), findsOneWidget);
      await tester.tap(find.byType(DropdownButton<MyColor>));
      await tester.pumpAndSettle();
      
      // fails
      // expect(find.byType(DropdownMenuItem<MyColor>), findsNWidgets(MyColor.values.length));
      
      // passes
      expect(find.byType(DropdownMenuItem<MyColor>), findsNWidgets(MyColor.values.length * 2));
    });
  });
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  MyColor selected = MyColor.blue;
  
  @override
  Widget build(BuildContext context) {
    return DropdownButton<MyColor>(
      value: selected,
      items: MyColor.values.map((col) {
        return DropdownMenuItem<MyColor>(
          child: Text(col.name),
          value: col,
        );
      }).toList(),
      onChanged: (value) {
        if (value == null) {
          return;
        }
        
        print('${value.name} selected');
        setState(() {
          selected = value;
        });
      }
    );
  } 
}

飞镖板:https ://dartpad.dev/?id=ce3eadff6bd98e6005817c70883451a0

我怀疑这与 Flutter 渲染场景的方式有关。我查看了 Flutter 存储库中下拉列表的小部件测试,但我没有看到我的设置和他们的设置有任何区别,但我也没有看到任何对find.byType(DropdownMenuItem). 有谁知道为什么会这样?还是我的代码有错误?

4

1 回答 1

0

DropdownButton最初渲染 an 时,所有项目都使用IndexedStack并基于所选值进行渲染,我们在顶部看到一个可见项目

  • 在那个阶段find.byType(DropdownMenuItem<MyColor>)会找到6个项目

一旦您点击DropdownButton一条_DropdownRoute路线,所有项目都会被推送

  • 在那个阶段find.byType(DropdownMenuItem<MyColor>)将找到 12 个项目(前 6 个 IndexedStack项目来自新路线,后 6 个项目来自新路线)所以在这个阶段项目的数量应该是双倍的,如颤振测试中所记录的那样

// 每个项目出现两次,一次在菜单中,一次在下拉按钮的 IndexedStack 中。

https://github.com/flutter/flutter/blob/504e66920005937b6ffbc3ccd6b59d594b0e98c4/packages/flutter/test/material/dropdown_test.dart#L2230

一旦您点击这些DropdownMenuItem项目,找到的小部件的数量将回到 6

于 2022-03-01T08:42:09.807 回答