gpt4 book ai didi

flutter - Riverpod - 如何在测试中访问提供者?

转载 作者:行者123 更新时间:2023-12-02 18:10:22 29 4
gpt4 key购买 nike

我有这个片段:

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++;
},
),
],
);
}
}

这是一个非常简化的代码,但其思想是它使用了状态提供程序。

我想编写一个测试并验证在一些操作之后,提供者处于特定状态(不依赖于 UI,在这里我可以使用 find.text(),但是我的状态可能要复杂得多)。

我想在抽取我的小部件后在我的测试中访问该模型:

await tester.pumpWidget(const CountWidget());

await tester.tap();
await tester.pump();

// ... Some other actions.

final currentCountState = // ?
expect(currentCountState, 3); // For example.

我该怎么做?

最佳答案

方案一

ProviderScope有一个静态方法 .containerOf它返回当前 context 的更接近 ProviderScopeProviderContainer

假设您想要使用键 Key('key') 为小部件关联/激活 WidgetRef ref,您可以获得它的 context tester.element .然后你可以使用ProviderScope.containerOf:

final context = tester.element(find.byType(Key('key')));
final providerContainter = ProviderScope.containerOf(context); // <- Your `ref`.

解决方案2

在这里,CountWidget extends ConsumerWidgetConsumerStatefulWidget 又扩展了 StatefulWidget

在riverpod的代码中,我们可以看到创建的state其实是一个_ConsumerState:

class _ConsumerState extends ConsumerState<ConsumerWidget> {
@override
WidgetRef get ref => context as WidgetRef;

@override
Widget build(BuildContext context) {
return widget.build(context, ref);
}
}

contextref 实际上是同一个对象。

这是因为在 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);
}
}

关联元素(用于context的是ConsumerStatefulElement:

class ConsumerStatefulElement extends StatefulElement implements WidgetRef {
// ...
}

所以在测试中,可以使用tester.element获取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.

关于flutter - Riverpod - 如何在测试中访问提供者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72472198/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com