I'm trying to write tests to my flutter widgets.
Let's say I have this stateful widget:
class A extends StatefulWidget {
const A();
@override
AState createState() => AState();
}
class AState extends State<A> {
bool value = false;
@override
Widget build(BuildContext context) {
final newValue = getNewValue(); // When the widget is rebuilt, I'm getting a value which can be `false` or `true`. I just want the widget to perfom actions if it changed;
if (value != newValue) {
setState(() {
value = newValue;
});
WidgetsBinding.instance.addPostFrameCallback((_) async {
if (mounted) {
// Do something, like show a snackbar for example
}
});
}
return const SizedBox.shrink();
}
}
When the widget rebuilds, it looks if the value from getNewValue
changed and rebuilds itself and then performs some actions with WidgetsBinding.instance.addPostFrameCallback
. (I only want the widget to perform this action when it rebuilds, and not subscribing to getNewValue
is wanted in my case).
Anyway, I wrote a test for this and where I pump the widget
// Mock `getNewValue` here so it returns `true`
const widget = A();
await tester.pumpWidget(widget);
await tester.pump();
// Verify the action after the `WidgetsBinding.instance.addPostFrameCallback` as been done
which works fine.
But now I want to force the widget to rebuild to test its behavior.
This is how I managed to do it (I call setState
):
// Mock `getNewValue` here so it returns `false` (change since last build)
tester.state<AState>(find.byType(A)).setState(() {});
await tester.pump();
await tester.pump();
// Verify the action after the `WidgetsBinding.instance.addPostFrameCallback` as been done
And this works fine too.
However, calling the setState
raises the warning
The member 'setState' can only be used within instance members of subclasses of 'package:flutter/src/widgets/framework.dart'.dart(invalid_use_of_protected_member)
and this trick won't work for a StatelessWidget
I was wondering what was the proper way to force a rebuild of a widget in a flutter test?