Kevin Shi
Kevin Shi

Reputation: 516

Flutter Mockito verify that callback passed to widget is called

I have a widget that takes a callback which is called when a button is pressed. I am trying to test that the callback is correctly invoked by the button.

I've tried mocking a Function class:

class MockCallback extends Mock implements Function {
  call() {}
}

Then passing an instance of the mock class to my widget and simulating a tap:

final mocked = MockCallback();
await tester.pumpWidget(
  MyWidget(myCallback: mocked),
);

final clearButtonFinder = find.byType(IconButton);
await tester.tap(clearButtonFinder);

verify(mocked()).called(1);

This results in an error on the verify call saying Used on a non-mockito object. If I put a print statement inside the mocked call, I can see that the tap is indeed calling it.

How can I verify that the callback passed to my widget is getting called once when the button is tapped?

Upvotes: 7

Views: 3679

Answers (2)

Adam Smaka
Adam Smaka

Reputation: 6413

This is how I solved this problem.

class MockCallback {
  int _callCounter = 0;
  void call() {
    _callCounter += 1;
  }

  bool called(int expected) => _callCounter == expected;
  void reset() {
    _callCounter = 0;
  }
}

No mockito needed.

Upvotes: 3

Igor Mak
Igor Mak

Reputation: 11

Probably it is not the best solution - use a stream:

final callbackCalled = BehaviorSubject<void>.seeded(null);

await tester.pumpWidget(
  MyWidget(myCallback: () { callbackCalled.add(null); }),
);

//... actions to trigger the callback

await expectLater(callbackCalled, emitsInOrder(<void>[null, null]));

You can use something meaningful instead of 'void' and 'null'.

Upvotes: 1

Related Questions