Search code examples
flutterdarttestinggesture

In widget tests, how can I perform a "pull-down" gesture?


I am using the RefreshIndicator widget - the usage looks something like this:

RefreshIndicator(
  onRefresh: () => refreshState(), // Invokes a method on a state object that is mocked in my test
  child: ...

Now I want to verify, that a "pull-down" gesture results in an invocation of refreshState:

testWidgets('Pulling down triggers refresh', (tester) async {
    var state = MockState(); // Class extending Mock from mocktail
    ...
    // pump widget, providing state as a ChangeNotifierProvider
    ...

    // SomeWidget is a child in the widget under test and effective child of RefreshIndicator, it's center is positioned towards the top of the screen
    var gesture = await tester.startGesture(tester.getCenter(find.byType(SomeWidget)));
    await gesture.moveBy(Offset(0, 750));
    await tester.pump();

    verify(() => state.refresh());
  });

Unfortunately, this results in a failing test, suggesting the method was not invoked:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
  No matching calls (actually, no calls at all).
(If you called `verify(...).called(0);`, please instead use `verifyNever(...);`.)

EDIT:

As suggested by Michael, using tester.drag together with tester.pumpAndSettle instead of tester.pump resolved the issue


Solution

  • You can use the drag method from flutter_test.

    API docs here: https://api.flutter.dev/flutter/flutter_test/WidgetController/drag.html

    Example usage:

    await tester.drag(find.byKey(ValueKey("Your Key")), Offset(0, 500));