Val*_*nal 5 dart flutter flutter-test riverpod
我有这个片段:
final countProvider = StateProvider<int>((ref) {
return 0;
});
class CountWidget extends ConsumerWidget {
const CountWidget();
@override
Widget build(BuildContext context, WidgetRef ref) {
final count = ref.watch(countProvider);
return Column(
children: [
Text(count.toString()),
IconButton(
icon: const Icon(Icons.add),
onPressed: () {
ref.read(countProvider.notifier).state++;
},
),
],
);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常简化的代码,但其想法是它使用状态提供程序。
我想编写一个测试并验证在执行某些操作后,提供程序处于特定状态(不依赖 UI,这里我可以使用find.text(),但我的状态可能要复杂得多)。
我想在抽出我的小部件后在测试中访问模型:
await tester.pumpWidget(const CountWidget());
await tester.tap();
await tester.pump();
// ... Some other actions.
final currentCountState = // ?
expect(currentCountState, 3); // For example.
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
ProviderScope有一个静态方法.containerOf,它返回当前的ProviderContainer更接近的。ProviderScopecontext
假设您想WidgetRef ref使用 key 获取小部件的关联/活动Key('key'),您可以使用 获取context它tester.element。然后你可以使用ProviderScope.containerOf:
final context = tester.element(find.byType(Key('key')));
final providerContainter = ProviderScope.containerOf(context); // <- Your `ref`.
Run Code Online (Sandbox Code Playgroud)
在这里,CountWidget延伸ConsumerWidget延伸ConsumerStatefulWidget延伸StatefulWidget。
在 Riverpod 的代码中,我们可以看到创建的状态实际上是一个_ConsumerState:
class _ConsumerState extends ConsumerState<ConsumerWidget> {
@override
WidgetRef get ref => context as WidgetRef;
@override
Widget build(BuildContext context) {
return widget.build(context, ref);
}
}
Run Code Online (Sandbox Code Playgroud)
context和ref实际上是同一个对象。
这是因为ConsumerStatefulWidget:
/// A [StatefulWidget] that can read providers.
abstract class ConsumerStatefulWidget extends StatefulWidget {
/// A [StatefulWidget] that can read providers.
const ConsumerStatefulWidget({Key? key}) : super(key: key);
@override
// ignore: no_logic_in_create_state
ConsumerState createState();
@override
ConsumerStatefulElement createElement() {
return ConsumerStatefulElement(this);
}
}
Run Code Online (Sandbox Code Playgroud)
关联元素(用于的元素context是ConsumerStatefulElement:
class ConsumerStatefulElement extends StatefulElement implements WidgetRef {
// ...
}
Run Code Online (Sandbox Code Playgroud)
所以在测试中,你可以使用tester.elementget ref:
await tester.pumpWidget(const CountWidget());
await tester.tap();
await tester.pump();
// ... Some other actions.
final ref = tester.element<ConsumerStatefulElement>(find.byType(CountWidget));
final currentCountState = ref.read(countProvider);
expect(currentCountState, 3); // For example.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3886 次 |
| 最近记录: |