iTranslated by AI
[Flutter] Not Just for Testing! How to Use Mockito in the lib Directory
Introduction
In testing, you often use Mockito to create mocks and stubs for classes.
However, I recently learned that Mockito can actually be used outside of test files, and I'd like to share how.
Target Audience
- Those who want to use Mockito even under the
libdirectory - Those who want to build UIs using mock data on screen for now
Author's Environment at the Time of Writing
[✓] Flutter (Channel stable, 3.27.1, on macOS 15.1 24B2082 darwin-arm64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.2)
[✓] VS Code (version 1.96.2)
Mock-Related Preparations
User Model
class User {
User({
required this.name,
required this.email,
required this.password,
});
final String name;
final String email;
final String password;
}
Class or Package to Mock
This time, we'll use SharedPreferences as an example, so let's install it.
Installing Mockito
Don't forget this either.
Creating Mocks
Create Mocks in lib
Just like in testing, we will create mocks in the file where we want to use them.
This time, we will mock the User model and SharedPreferences.
import 'package:flutter/material.dart';
import 'package:mockito/annotations.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:simple_base/domains/user.dart';
@GenerateNiceMocks([
MockSpec<SharedPreferences>(),
MockSpec<User>(),
])
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
...
}
Configure build.yaml for Automatic Generation
Running build_runner as is will not generate mocks.
So, create a build.yaml file directly under the root directory and enter the following:
targets:
$default:
builders:
mockito|mockBuilder:
generate_for:
- test/**.dart
- lib/**.dart
This enables automatic generation not only for the test directory but also for the lib directory.
Try running the automatic generation.
Set Stubs for Mocks
Just like creating stubs in tests, you can set stubs using when.
import 'package:flutter/material.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:simple_base/domains/user.dart';
import 'package:simple_base/main.mocks.dart';
@GenerateNiceMocks([
MockSpec<SharedPreferences>(),
MockSpec<User>(),
])
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
final user = MockUser();
when(user.name).thenReturn('John Doe');
when(user.email).thenReturn('john@example.jp');
when(user.password).thenReturn('password');
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
spacing: 20,
children: [
Text(
'Name: ${user.name} \nEmail: ${user.email} '
'\nPassword: ${user.password}',
),
ElevatedButton(
onPressed: () {
final prefs = MockSharedPreferences();
when(prefs.getString('key')).thenReturn('Mock value obtained');
final value = prefs.getString('key');
if (value == null) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(value)),
);
},
child: const Text('Tap Mock Method'),
),
],
),
),
),
);
}
}

Precautions
While this approach might be acceptable for a mere sample project, for a release-oriented project, you should handle it with more caution.
First, I believe it's necessary to limit the files for which build.yaml allows automatic generation. This is to prevent accidental inclusion in production files.
For example, here's how to specify concrete files:
targets:
$default:
builders:
mockito|mockBuilder:
generate_for:
- test/**.dart
- lib/debug/debug_screen.dart # <= 💡 Specify files
And let's say, based on the example above, you limit it to debug_screen only.
This debug_screen should preferably be restricted to only be displayed in development environments using Flavor or similar mechanisms.
The separation of development environments is explained here:
Conclusion
Typically, Mockito is often used in testing environments,
but it simplifies the handling of mock data during debugging and development.
By effectively utilizing this method, you can proceed with development while handling mock data more flexibly.
Please give it a try!
Discussion