Reputation: 270
I tried selecting a DropdownButton item
like this:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:dropdown_test_sample/main.dart';
void main() {
testWidgets('Select Dropdown item test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const SampleApp());
final dropdown = find.byKey(const ValueKey('dropdown'));
await tester.tap(dropdown);
await tester.pumpAndSettle();
final dropdownItem = find.byKey(const ValueKey('First item key'));
await tester.tap(dropdownItem);
await tester.pumpAndSettle();
});
}
But unfortunately, It throws this exception:
There seems to be something that keeps creating an identical DropdownButton item
with the same key, thereby making the widget test fail because, tester.tap()
cannot "tap" on two widgets at the same time.
Here's the full implementation of the DropdownButton
widget:
import 'package:flutter/material.dart';
void main() {
runApp(const SampleApp());
}
class SampleApp extends StatelessWidget {
const SampleApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dropdown Test Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Home(),
);
}
}
class Home extends StatelessWidget {
const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(
child: DummyDropdown(
key: ValueKey('dropdown'),
),
),
);
}
}
class DummyDropdown extends StatefulWidget {
const DummyDropdown({Key? key}) : super(key: key);
@override
State<DummyDropdown> createState() => _DummyDropdownState();
}
class _DummyDropdownState extends State<DummyDropdown> {
String? text = 'Dropdown';
String? textValue;
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: textValue,
underline: Container(),
dropdownColor: Theme.of(context).cardColor,
style: Theme.of(context).textTheme.bodyText2,
hint: Text(
text!,
),
icon: const Icon(Icons.keyboard_arrow_down),
onChanged: (newValue) {
setState(
() {
textValue = newValue;
text = newValue;
},
);
},
items: <String>['First item', 'Second item', 'Third item']
.map<DropdownMenuItem<String>>(
(value) {
return DropdownMenuItem<String>(
value: value,
key: ValueKey('$value key'),
child: Text(
value,
),
);
},
).toList(),
);
}
}
Upvotes: 10
Views: 7980
Reputation: 494
Widget testing in drop down button is different than other widgets please see here for more. In this is case select the last element from the text "First Item".This will work.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:testapp/main.dart';
void main() {
testWidgets('Select Dropdown item test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const SampleApp());
final dropdown = find.byKey(const ValueKey('dropdown'));
await tester.tap(dropdown);
await tester.pumpAndSettle();
///if you want to tap first item
final dropdownItem = find.text('First item').last;
await tester.tap(dropdownItem);
await tester.pumpAndSettle();
});
}
The issue is here. when we tap the drop down one was already selected and other one is not selected. So you can test that item using the text value.
final dropdownItem = find.text('First item').last;
Upvotes: 21