Loading...
Loading...
Use when creating, writing, fixing, or reviewing tests in a Flutter project. Covers unit tests, widget tests, integration tests, Riverpod provider testing, and Mockito mocking. Provides Given-When-Then patterns, layer isolation strategies, and test setup for GetIt, SharedPreferences, and FakeDatabase.
npx skill4agent add harishwarrior/flutter-claude-skills flutter-testerflutter_testdart run build_runner build@GenerateMocksfvm flutter testflutter test| What you're testing | Reference file |
|---|---|
| Repository, DAO, Service logic | |
| Widget UI, interactions, dialogs, navigation | |
| Riverpod provider state, mutations, lifecycle | |
| Layer | What to test | What to mock |
|---|---|---|
| Repository | Data coordination between sources | DAOs, APIs, Logger |
| DAO | Database CRUD operations | Use real in-memory DB, mock Logger |
| Provider | State management and transitions | Services, Repositories |
| Service | Business logic and workflows | Repositories, Network clients |
| Widget | UI behaviour and interactions | Provider dependencies (via overrides) |
test('Given valid data, When fetchUsers called, Then returns user list', () async {
// Arrange (Given)
when(mockDAO.fetchAll()).thenAnswer((_) async => expectedUsers);
// Act (When)
final result = await repository.fetchUsers();
// Assert (Then)
expect(result, equals(expectedUsers));
verify(mockDAO.fetchAll()).called(1);
});group('UserRepository', () {
group('fetchUsers', () {
setUp(() { /* init mocks, register with GetIt */ });
tearDown(() => GetIt.I.reset()); // Always reset GetIt
test('Given success ... When ... Then ...', () { });
test('Given error ... When ... Then ...', () { });
});
});([IUserDAO, IUserAPI, ILogger])
void main() { ... }dart run build_runner build@GenerateMockssetUp(() {
mockDAO = MockIUserDAO();
mockLogger = MockILogger();
GetIt.I
..registerSingleton<IUserDAO>(mockDAO)
..registerSingleton<ILogger>(mockLogger);
});
tearDown(() => GetIt.I.reset()); // Critical — always resetclass FakeLogger extends ILoggerMockILoggerwhen()verify()thenThrow()| Scenario | Key pattern |
|---|---|
| Test a repository | Mock DAO + API → inject into repository constructor |
| Test a DAO | |
| Test a Riverpod provider | |
| Test a widget | Set screen size, use |
| Test a loading state | Use |
| Test platform-specific UI | |
| Test GoRouter navigation | |
flutter test --coverage # All tests with coverage
flutter test test/path/to/test.dart # Specific file
flutter test --plain-name "Given valid data" # Filter by name
genhtml coverage/lcov.info -o coverage/html # Generate HTML coverage report
# Prefix any command with `fvm` if using Flutter Version Manager| Mistake | Fix |
|---|---|
| Mocking a provider directly | Override its dependencies: |
Missing | Tests pollute each other — always reset |
| Use |
| Finding widgets by text string | Use |
| No screen size in widget tests | Add |
Not resetting | Set to |
| Write |
GetIt.I.reset()tearDowntearDowntearDownfind.byKey()physicalSizedevicePixelRatiodebugDefaultTargetPlatformOverride = nullFuture.delayedverify()verifyNever()