Mocking

Adding a use-case for a widget that has external dependencies can be challenging. In this guide, we'll explore how to mock these dependencies to make cataloging the widget easier.

In the following example, the HomePage widget depends on the UserProvider to display the user's name.

class UserProvider with ChangeNotifier {
  // For simplicity, we're hardcoding the user's name.
  // In a real-world scenario, this would be fetched from an API or a database.
  String user => "John Doe";
}
class UserTile extends StatelessWidget {
  const UserTile({super.key});

  @override
  Widget build(BuildContext context) {
    return Consumer<UserProvider>(
      builder: (context, provider, child) {
        return Text(provider.user);
      },
    );
  }
}

Approach I: Extraction

The simplest method to catalog UserTile is to extract the UserProvider dependency into a parameter.

class UserTile extends StatelessWidget {
  const UserTile({
    super.key,
    required this.user,
  });

  final String user;

  @override
  Widget build(BuildContext context) {
    return Text(user);
  }
}
@widgetbook.UseCase(name: 'Primary', type: UserTile)
Widget buildUserTile(BuildContext context) {
  return UserTile(
    user: 'John'
  );
}

Approach II: Mocking Libraries

Not in all cases, you can extract the dependency. In some case you need to mock the dependency, for example if you are cataloging a "screen" widget.

  1. Add a mocking library to your widgetbook/pubspec.yaml file.

    It might feel weird seeing mocktail used as a dependency and not a dev_dependency, but the whole widgetbook app is a dev tool app.

    dependencies:
      # ...
      mocktail: ^1.0.0
    
  2. Mock UserProvider in the use-case builder function as follows

    class MockUserProvider extends Mock implements UserProvider {}
    
    @widgetbook.UseCase(name: 'Primary', type: UserTile)
    Widget buildUserTile(BuildContext context) {
     return ChangeNotifierProvider<UserProvider>(
       create: (_) {
         final provider = MockUserProvider();
         when(() => provider.user).thenReturn('Mocked User');
    
         return provider;
       },
       child: UserTile(),
     );
    }