--- 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>>()); 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