使用显式容器让测试保持稳定。
大多数测试场景都能直接映射到 ProviderContainer 的接口:read、invalidate、refresh、listen,以及按实例覆盖。
测试策略
将测试拆分为纯容器测试和 widget 集成测试。
纯 Dart
直接使用 ProviderContainer 做 read / invalidate / refresh 断言
覆盖
通过 overrideWith / overrideWithValue 按提供者实例覆盖
Widget 测试
注入外部容器,并显式释放
提示
除非指定 fireImmediately: true,否则 ProviderContainer.listen 不会发出初始值。
测试命令与检查清单
运行完整测试集,并确认 autoDispose 场景中没有悬挂计时器泄漏。
命令
检查清单
- 在 tearDown 中释放外部注入的 ProviderContainer。
- 当监听断言需要初始状态时,使用 fireImmediately: true。
- 对于 autoDispose 测试,推进虚拟时间超过 autoDisposeDelay。
示例:按参数覆盖
类似 family 的提供者会根据工厂函数创建出的每个实例分别覆盖。
class ProductById extends Provider<Product> {
ProductById(this.id) : super.args((id,));
final String id;
@override
Product build(ref) {
final repo = ref.watch(productRepoProvider);
return repo.fetch(id);
}
}
final container = ProviderContainer(
overrides: [
productByIdProvider('a').overrideWithValue(const Product(id: 'a', name: 'stub')),
],
);
// 断言并清理
container.dispose();
这个模式与 README 以及 miniriverpod 仓库中的上游测试保持一致。
Widget 测试在释放外部容器前,应该先卸载 widget。
使用 fake_async 验证 autoDispose 延迟与 keepAlive 行为。