.overrideWithValue
Replaces a provider with a fixed value instead of executing its original logic.
What is it?
.overrideWithValue is a provider modifier that allows you to override a provider with a constant prebuilt value.
Unlike .overrideWith, which replaces the provider logic, .overrideWithValue directly injects an already created value into the provider system.
This makes it the simplest form of overriding.
Why does it exist?
In many cases (especially testing and UI previews), you don’t need custom logic — you just want a fixed value.
Without .overrideWithValue, you would still need to wrap simple values inside a function using .overrideWith.
.overrideWithValue removes that unnecessary boilerplate.
It is designed for:
- Tests
- Mock UI states
- Static dependency injection
- Predefined data setups
Syntax
Basic Usage
final counterProvider = Provider<int>((ref) => 10);
Explanation:
- A simple provider returning an integer.
Overriding with Value
ProviderScope(
overrides: [
counterProvider.overrideWithValue(99),
],
child: const MyApp(),
);
Explanation:
- The provider is replaced with a fixed value.
- No function is executed.
- The value is used directly wherever the provider is read.
With Complex Objects
final userProvider = Provider<User>((ref) {
return User(id: 1, name: 'Default');
});
Override:
ProviderScope(
overrides: [
userProvider.overrideWithValue(
User(id: 99, name: 'Mock User'),
),
],
child: const MyApp(),
);
Explanation:
- A fully constructed object is injected.
- No recomputation or factory logic is used.
Mental Model
Think of .overrideWithValue as direct injection into the provider graph.
Without override:
Provider → executes logic → produces value
With overrideWithValue:
Provider → skipped → injected value used directly
It completely bypasses provider creation logic.
Examples
Simple Example
final themeProvider = Provider<String>((ref) => 'Light');
Override:
ProviderScope(
overrides: [
themeProvider.overrideWithValue('Dark'),
],
child: const MyApp(),
);
Explanation:
- The app behaves as if the theme is always "Dark".
- No provider logic is executed.
Real-World Example
final authProvider = Provider<User?>((ref) {
return null;
});
Test override:
ProviderScope(
overrides: [
authProvider.overrideWithValue(
User(id: 1, name: 'Test User'),
),
],
child: const MyApp(),
);
Explanation:
- Authentication state is mocked.
- Useful for bypassing login flows in tests.
UI Preview Example
final productProvider = Provider<Product>((ref) {
throw UnimplementedError();
});
Override:
ProviderScope(
overrides: [
productProvider.overrideWithValue(
Product(id: 'P1', name: 'Preview Product'),
),
],
child: const ProductCard(),
);
Explanation:
- Enables UI development without backend or API.
When to Use
Use .overrideWithValue when:
- You already have a fully constructed object
- Writing widget tests
- Creating UI previews or storybook setups
- Injecting static mocks
- Avoiding async or computation logic
When NOT to Use
Avoid .overrideWithValue when:
- You need to compute or fetch data dynamically
- The value depends on runtime logic
- You need different behavior per test scenario
- The provider requires setup or cleanup logic
In those cases, use .overrideWith instead.
Best Practices
- Use for simple and static overrides only
- Prefer
.overrideWithfor anything involving logic - Keep test overrides close to test setup code
- Avoid large object graphs unless necessary
- Use factory methods for complex mock creation
Common Mistakes
Using overrideWithValue for Dynamic Data
Wrong
counterProvider.overrideWithValue(Random().nextInt(100));
This makes the value unpredictable at test time.
Correct
counterProvider.overrideWithValue(42);
Keep values deterministic.
Trying to Use Async Logic
Wrong
userProvider.overrideWithValue(fetchUser());
This returns a Future, not a value.
Correct
userProvider.overrideWithValue(User(id: 1, name: 'Mock'));
.overrideWithValue does not support async computation.
Overusing It for Complex Providers
Wrong
ProviderScope(
overrides: [
complexService.overrideWithValue(ComplexServiceImpl(...)),
],
);
This bypasses lifecycle management unnecessarily.
Correct
Use .overrideWith when setup logic is required.
Related APIs
.overrideWithProviderScope.family.autoDisposeProviderContainer
Summary
.overrideWithValue replaces a provider with a fixed prebuilt value. It is the simplest form of overriding and is best suited for tests, UI previews, and static dependency injection. Unlike .overrideWith, it does not execute any logic — it directly injects the value into Riverpod’s dependency graph.