57 lines
1.5 KiB
Cheetah
57 lines
1.5 KiB
Cheetah
---
|
|
description: "Riverpod testing conventions for {{PROJECT_NAME}}"
|
|
alwaysApply: false
|
|
---
|
|
|
|
# Riverpod Testing Standards — {{PROJECT_NAME}}
|
|
|
|
## Test pattern
|
|
```dart
|
|
// {{TEST_PATTERN}}
|
|
|
|
void main() {
|
|
late ProviderContainer container;
|
|
late MockProductRepository mockRepo;
|
|
|
|
setUp(() {
|
|
mockRepo = MockProductRepository();
|
|
container = ProviderContainer(overrides: [
|
|
productRepositoryProvider.overrideWithValue(mockRepo),
|
|
]);
|
|
});
|
|
|
|
tearDown(() => container.dispose()); // ALWAYS dispose
|
|
|
|
test('ProductsNotifier loads products successfully', () async {
|
|
when(() => mockRepo.getProducts()).thenAnswer((_) async => [fakeProduct]);
|
|
|
|
final notifier = container.read(productsProvider.notifier);
|
|
await notifier.loadProducts();
|
|
|
|
final state = container.read(productsProvider);
|
|
expect(state, isA<AsyncData<List<Product>>>());
|
|
expect(state.value, [fakeProduct]);
|
|
});
|
|
}
|
|
```
|
|
|
|
## Widget tests with Riverpod
|
|
```dart
|
|
testWidgets('ProductScreen shows shimmer while loading', (tester) async {
|
|
await tester.pumpWidget(
|
|
ProviderScope(
|
|
overrides: [
|
|
productsProvider.overrideWith((ref) => const AsyncLoading()),
|
|
],
|
|
child: const MaterialApp(home: ProductScreen()),
|
|
),
|
|
);
|
|
expect(find.byType(ProductShimmer), findsOneWidget);
|
|
});
|
|
```
|
|
|
|
## Rules
|
|
- **Never** use a real `ProviderScope` in unit tests — always use `ProviderContainer` with overrides
|
|
- `addTearDown(container.dispose)` in every test that creates a container
|
|
- Test all three `AsyncValue` states: loading, data, error
|