# 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.

## Video tutorial

<YouTube id="ytu7ADEsukE?start=1410&end=1730" />

## Example

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

```dart
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";
}
```

```dart
class UserTile extends StatelessWidget {
  const UserTile({super.key});

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

For this example, the Widget tree for your `HomePage` widget in your app might look like this:

```tree
App
└── UserProvider
    └── HomePage
        └── UserTile
            └── Consumer<UserProvider>
                └── Text
```

## Problem

If the `UserTile` is cataloged using the following code

```dart
Widget userTileUseCase(BuildContext context) {
  return UserTile();
}
```

Flutter throws an error indicating that a `UserProvider` is missing from the Widget tree, as the `Consumer` within the `UserTile` depends on the `UserProvider`.

```tree
WidgetbookApp
└── UserTile
    └── Consumer<UserProvider>         ❌ Error: UserProvider not found
        └── Text
```

To catalog the `UserTile` widget, you need to do **one of the following**:
1. Remove the dependency of the `UserTile` by using property extraction.
1. Provide the `UserProvider` to the Widget tree. 

## Approach I: Extraction

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

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

  final String user;

  @override
  Widget build(BuildContext context) {
    return Text(user);
  }
}
```

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

Extracting the dependency into a parameter will also change your Widget tree structure of your app

```tree
App
└── UserProvider
    └── HomePage
        └── Consumer<UserProvider>
            └── UserTile
                └── Text
```

The Widget tree in Widgetbook will also change accordingly 

```tree
WidgetbookApp
└── UserTile
    └── Text
```

## 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.

   <Info>
     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.
   </Info>

   ```yaml
   dependencies:
     # ...
     mocktail: ^1.0.0
   ```

2. Mock `UserProvider` in the use-case builder function as follows

   ```dart
   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(),
    );
   }
   ```

In this approach, the Widget tree of your app stays the same

```tree
App
└── UserProvider
    └── HomePage
        └── UserTile
            └── Consumer<UserProvider>
                └── Text
```

But the Widget tree in Widgetbook will change according to your mocking

```tree
WidgetbookApp
└── MockUserProvider
    └── UserTile
        └── Consumer<UserProvider>
            └── Text
```