I have a widget test that taps an item in the DropdownButton
. That should fire the onChanged
callback but it doesn't. Here is the test code. The mock is Mockito.
void main() {
//Use a dummy instead of the fake. The fake does too much stuff
final mockServiceClient = MockTheServiceClient();
final apiClient = GrpcApiClient(client: mockServiceClient);
when(mockServiceClient.logEvent(any))
.thenAnswer((_) => MockResponseFuture(LogEventResponse()));
testWidgets("select asset type", (tester) async {
//sets the screen size
tester.binding.window.physicalSizeTestValue = const Size(3840, 2160);
// resets the screen to its orinal size after the test end
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
await tester.pumpWidget(AssetApp(apiClient), const Duration(seconds: 5));
//Construct key with '{DDLKey}_{Id}'
await tester
.tap(find.byKey(ValueKey("${assetTypeDropDownKey.value}_PUMP")));
await tester.pumpAndSettle(const Duration(seconds: 5));
verify(mockServiceClient.logEvent(any)).called(1);
});
}
This is the build method of the widget:
@override
Widget build(BuildContext context) {
return DropdownButton<DropDownItemDefinition>(
underline: Container(),
dropdownColor: Theme.of(context).cardColor,
hint: Text(
hintText,
style: Theme.of(context).textTheme.button,
),
//TODO: Use the theme here
icon: Icon(
Icons.arrow_drop_down,
color: Theme.of(context).dividerColor,
),
value: getValue(),
onChanged: (ddd) {
setState(() {
onValueChanged(ddd!);
});
},
items: itemss.map<DropdownMenuItem<DropDownItemDefinition>>((value) {
return DropdownMenuItem<DropDownItemDefinition>(
key: ValueKey(
"${(key is ValueKey) ? (key as ValueKey?)?.value.toString() :
''}_${value.id}"),
value: value,
child: Tooltip(
message: value.toolTipText,
child: Container(
margin: dropdownPadding,
child: Text(value.displayText,
style: Theme.of(context).textTheme.headline3))),
);
}).toList(),
);
}
Note that the onValueChanged
function calls the logEvent
call. The onChanged
callback never happens and the test fails. This is the code it should fire.
Future onAssetTypeChange(DropDownItemDefinition newValue) async {
await assetApiClient.logChange(record.id, newValue, DateTime.now());
}
Why does the callback never fire?
Note: I made another widget test and the Mock does verify that the client was called correctly. I think there is some issue with the callback as part of the widget test.