Dart Mockito - How to mock while keep the original implementation?

Viewed 709

I would like to write some integration tests on my flutter app. To do so I am using the package Mockito.


I would like to mock a class but also keep its original implementation.

Let's say I have a model MyModel (which can be complex) and a widget using it.

class MyModel {
    void complexCallback() {}
}

class MyWidget extends StatelessWidget {
    const MyWidget(this.model);
    
    final MyModel model;
    
    @override
    Widget build(BuildContext context) {}
}

I would like to be able in a test to mock MyModel to verify the callback function is called (for example after a tap on a button), but I would also want MyModel to behave as it should to verify the repercussions on the screen (rebuild of the widget with different values for example).

testWidget('Test MyModel and MyWidget', (WidgetTester tester) async {
    final model = MyModel(); // <- Cannot verify here because it is not mocked, if I replace by MockMyModel or FakeMyModel, the button doesn't do anything anymore
    await tester.pumpWidget(MyWidget(model));

    await tester.tap(find.byType(IconButton));  // <- Tap on a button for example

    expect(find.text('Button tapped'), findsOneWidget); // <- Test change on the screen - works with MyModel but not with MockMyModel and FakeMyModel
    expect(verify(model.complexCallback(captureAny)).captured, ['buttonID']); // <- Test callback function - works with MockMyModel or FakeMyModel but not with MyModel
});

The issue I have is that if I run the test as it is, MyModel is not mocked, so verify won't work.

If I mock it using Mock or Fake from Mockito:

class MockMyModel extends Mock implements MyModel {}

or

class FakeMyModel extends Fake implements MyModel {}

I will lose the implementation of MyModel and then, the screen won't change after a tap. And I don't really want to override all the methods of MyModel which can be pretty big and complex. Also if I rewrite it, I will then test my overridden implementation and not the original one which is not really the point.


Any idea how I could achieve it?

0 Answers
Related