为啥提供者组合不会在飞镖测试中通知其新状态?

Posted

技术标签:

【中文标题】为啥提供者组合不会在飞镖测试中通知其新状态?【英文标题】:Why a provider combination will not notify its new state in a dart test?为什么提供者组合不会在飞镖测试中通知其新状态? 【发布时间】:2022-01-23 20:11:09 【问题描述】:

我是 Riverpod 的新手,我正在关注有关提供程序组合的文档。

在组合提供程序并在 dart 测试(在 test_widgets 之外)中测试输出时,我遇到了我不理解的行为。 我试图用一个简单的代码来概述它,如下所示:

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:riverpod/riverpod.dart';

final positiveProvider = StateProvider<int>((ref) => 0);

final negativeProvider = StateProvider<int>((ref) => 0);

final combinedProvider = Provider<int>((ref) 
  final positive = ref.watch(positiveProvider);
  final negative = ref.watch(negativeProvider);

  print('Counter state: $positive - negative');
  return positive - negative;
);

class CounterListener extends Mock 
  void call(int? previous, int value);


void main() 
  test('Test riverpod provider combination', () 
    final container = ProviderContainer();
    addTearDown(container.dispose);

    final counterListener = CounterListener();

    container.listen(combinedProvider, counterListener, fireImmediately: true);

    verify(counterListener.call(null, 0)).called(1);

    container.read(positiveProvider.state).state = 1;

    verify(counterListener.call(0, 1)).called(1);
  );

我得到了这个结果:

Counter state: 0 No matching calls. All calls: [VERIFIED] CounterListener.call(null, 0) (If you called `verify(...).called(0);`, please instead use `verifyNever(...);`.) package:test_api              fail
_VerifyCall._checkWith
_makeVerify.<fn> main.<fn>

✖ Test riverpod provider combination Exited (1)

行为是组合的提供者不会自动触发其内部函数,我认为它会这样做。

我不确定我是否误解了组合提供程序所需的编码模式,或者它是否来自测试中的容器逻辑,不是“观察”而是“听”。

感谢您的帮助,

【问题讨论】:

【参考方案1】:

提供程序代码是正确的,但测试的代码不是。

在所有代码执行完成之前,容器拆除,方法调用后的第二次验证发生。

将拆解放在最后,然后调用一个简单的 Future.delayed after 方法即可解决问题。

【讨论】:

以上是关于为啥提供者组合不会在飞镖测试中通知其新状态?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的单元测试在 Chrome 中通过而在 PhantomJS 中失败?

当提供者组件父状态发生变化时,为啥不能更新子组件中的值(带有反应上下文)?

为啥颤振分析与飞镖分析不同?

无奈\不解,UvaOJ为啥不提供出错时的测试数据

如何取消颤振/飞镖集团中的“等待”

为啥我的添加好友测试路由在 insomina 中通过了 200 OK,但是当我调用获取所有用户时它没有嵌套?