Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test a callback function in a Flutter widget

I have a custom Flutter widget, RadioSelect, which accepts an array of options and a callback function when one of those options is pressed. The callback is called with the selected option passed as it's only parameter. I'm trying to write a test which verifies that the callback was called and checks that the returned parameter is correct but I'm not sure how to structure it. What's a sensible way to check that a standalone callback function was called?

  await tester.pumpWidget(
    StatefulBuilder(
      builder: (BuildContext context, StateSetter setState) {
        return MaterialApp(
          home:  RadioSelect(
                                ["option1","option2", "option3"], 
                                // callback function passed here
                                ),
            );
      },
    ),
  );

expect(find.text('option1'), findsOneWidget);

await tester.press(find.text('option2'));

await tester.pump();

// test for callback here
like image 704
tooba Avatar asked Sep 15 '25 07:09

tooba


2 Answers

You can also use a Completer

testWidgets('callback', (WidgetTester tester) async {
  final completer = Completer<void>();

  await tester.pumpWidget(
    MaterialApp(
      home: FlatButton(
        child: Text('press me'),
        onPressed: completer.complete,
      ),
    ),
  );

  await tester.tap(find.byType(FlatButton));

  expect(completer.isCompleted, isTrue);
});

source: https://luksza.org/2020/testing-flutter-callbacks/

like image 134
Jacob Sánchez Avatar answered Sep 17 '25 20:09

Jacob Sánchez


In the body of a Callback function, you can print the received arguments, and then expect if it prints correctly.

Here is another sample doing a similar test:

CHILD OF A TESTING WIDGET:

...
...

Checkbox(
     key: Key('StatusCheckBox'),
     value: isCompleted,
     onChanged: (_) => toggleCompletionStatus(),
 ),

...
...

I'm passing print('Call') as a body of toggleCompletionStatus()

Which can be tested this way:

expectLater(
        () => tester.tap(find.byKey(Key('StatusCheckBox'))), prints('Call\n'));
like image 20
Milind Mevada Avatar answered Sep 17 '25 22:09

Milind Mevada