小部件测试 DropdownButton 发现重复的 DropdownMenuItems
Widget testing DropdownButton finds duplicate DropdownMenuItems
我正在尝试为我的应用程序中的 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渲染场景的方式有关。我查看了 widget tests for the dropdown in the Flutter repo,但没有发现我的设置与他们的有任何区别,而且我也没有看到对 find.byType(DropdownMenuItem)
的任何调用。有谁知道为什么会这样?还是我的代码有错误?
最初呈现 DropdownButton
时,所有项目都使用 IndexedStack
呈现,并且根据所选值,我们在顶部看到一个可见项目
- 在那个阶段
find.byType(DropdownMenuItem<MyColor>)
会找到 6
项目
点击 DropdownButton
后,_DropdownRoute
路线为 pushed,其中包含所有项目
- 在那个阶段
find.byType(DropdownMenuItem<MyColor>)
会找到 12
项(前 6 项来自 IndexedStack
,后 6 项来自 IndexedStack
项目来自新路线)
因此,在这个阶段,项目的数量应该是 flutter 测试中记录的两倍
// Each item appears twice, once in the menu and once
// in the
dropdown button's IndexedStack.
点击 DropdownMenuItem
个项目后,找到的小部件数量将恢复为 6
我正在尝试为我的应用程序中的 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渲染场景的方式有关。我查看了 widget tests for the dropdown in the Flutter repo,但没有发现我的设置与他们的有任何区别,而且我也没有看到对 find.byType(DropdownMenuItem)
的任何调用。有谁知道为什么会这样?还是我的代码有错误?
最初呈现 DropdownButton
时,所有项目都使用 IndexedStack
呈现,并且根据所选值,我们在顶部看到一个可见项目
- 在那个阶段
find.byType(DropdownMenuItem<MyColor>)
会找到 6 项目
点击 DropdownButton
后,_DropdownRoute
路线为 pushed,其中包含所有项目
- 在那个阶段
find.byType(DropdownMenuItem<MyColor>)
会找到 12 项(前 6 项来自IndexedStack
,后 6 项来自IndexedStack
项目来自新路线) 因此,在这个阶段,项目的数量应该是 flutter 测试中记录的两倍
// Each item appears twice, once in the menu and once // in the dropdown button's IndexedStack.
点击 DropdownMenuItem
个项目后,找到的小部件数量将恢复为 6