How can I find `FlatButton.icon` in a Flutter tests?

Viewed 2700

In my app I create a button using FlatButton.icon (Flutter docs). Now I'm trying to find the button during testing.

I've tried

find.byType(MaterialButton); // -> zero widgets
find.byType(FlatButton); // -> zero widget

The strange thing is that I can find the text for the button

find.text('my button text');

and I can also find the icon for the button

find.byType('Icon');

I'm not sure what I should be searching for to find the button.

3 Answers

Alright, so I wasn't able to find the FlatButton itself, but it's easy to find the icon with . . .

find.byIcon(Icons.yourIcon);

See the relevant docs for more info: flutter_test find.byIcon

Even though the question might seem quite old, I'd like to expand on the topic since none of the answers actually shows how to find the FlatButton itself. The problem is that FlatButton.icon is not a constructor, but a factory creating a different object _FlatButtonWithIcon extending FlatButton, which is apparently only available inside its file. In the meantime, find.byType only looks for widgets by an identical type - it doesn't work for derived types.

So, to return the object itself: find.ancestor(of: find.byIcon(Icons.your_icon), matching: find.byWidgetPredicate((widget) => widget is FlatButton)). This approach let us get the button object and therefore test its properties (e.g., onPressed) or child widgets (e.g., label) by calling find.descendant.

I faced this issue and had some help from the flutter discord server, and here I am sharing the solution: NOTE: you have to use dynamic for the returned widget because the class is private.

void main() {
  testWidgets('TextButton.icon test', (WidgetTester tester) async {
    const IconData iconData = Icons.add;

    await tester.pumpWidget(
      MaterialApp(
        home: Center(
          child: TextButton.icon(
            onPressed: () { },
            icon: const Icon(iconData),
            label: const Text('text button'),
          ),
        ),
      ),
    );
    final dynamic textButtonWithIconWidget = tester.widget(find.byWidgetPredicate((Widget widget) => '${widget.runtimeType}' == '_TextButtonWithIconChild'));
    expect(textButtonWithIconWidget.icon, const Icon(iconData));
  });
}
Related