tooba
tooba

Reputation: 569

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

Upvotes: 4

Views: 4721

Answers (2)

Jacob Sánchez
Jacob Sánchez

Reputation: 459

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/

Upvotes: 8

Milind Mevada
Milind Mevada

Reputation: 3285

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'));

Upvotes: 2

Related Questions