How to test a callback function in a Flutter widget

2,769

Solution 1

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/

Solution 2

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'));
Share:
2,769
tooba
Author by

tooba

Updated on December 15, 2022

Comments

  • tooba
    tooba over 1 year

    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