【问题标题】:Flutter Widget Test wait for animationFlutter Widget Test 等待动画
【发布时间】:2021-05-29 19:32:50
【问题描述】:

我有一个类似的小部件测试:

testWidgets('Widget test', (WidgetTester tester) async {
  provideMockedNetworkImages(() async {
    final widget = MyWidget();

    await WidgetTestFunctions.pumpWidgetTest(
      tester,
      widget,
    );

    // ....

    await tester.tap(find.byType(MyWidget));
    await tester.pump(new Duration(milliseconds: 3000));

    // ....

    expect(widget.value, myValue);
  });
});

以及widget的on-tap方法的如下实现:

_onButtonPressed() async {      
  await animationController.forward();
  setState(() {
    // ...
    // Calls method that changes the widget value.
  });           
}

我遇到的问题是在测试中调用animationController.forward() 方法后,setState 部分没有被执行。我应该如何等待此方法正确完成?在应用运行时,这部分代码被正确调用。

await tester.pump(new Duration(milliseconds: 3000)); 似乎无法正常工作,动画的持续时间为 1500 毫秒,并且您可以看到泵的持续时间是两倍。

【问题讨论】:

  • 你找到答案了吗?
  • @SilkeNL 还没有
  • 你试过没有持续时间的泵吗? await tester.tap(find.byType(MyWidget)); await tester.pump(new Duration(milliseconds: 3000));
  • 我遇到了类似的问题,在AnimationController.forward 调用后找不到小部件。我通过将ValueKey 分配给我要测试的小部件来“修复”这个问题,然后使用该密钥来验证信息。不过,这不是一个解决方案,而更像是一种 hack。
  • 你好@notarealgreal 你还没有找到任何解决方案?

标签: animation widget widget-test-flutter


【解决方案1】:

我遇到了同样的问题,这就是发生的事情。

当你这样做时

await animationController.forward();

您等待的不是简单的Future<void>,而是TickerFuture(扩展Future<void>)。

由于某种原因,在我的测试中,animationController.forward() 中的一些 TickerFutures 被取消了。

TickerProvider 的文档中,它说:

如果 Ticker 在没有被停止的情况下被释放,或者如果它在被取消设置为 true 的情况下被停止,那么这个 Future 将永远不会完成。

这个类像普通的 Future 一样工作,但有一个额外的属性 orCancel,如果返回 TickerFuture 的 Ticker 停止并取消设置为 true,或者如果它在没有设置的情况下被处置被阻止了。

要在此未来解决或报价单被取消时运行回调,请使用 whenCompleteOrCancel。

现在,whenCompleteOrCancel 的问题是它返回 void(而不是 Future<void>,所以我们等不及了。

这就是我所做的(灵感来自whenCompleteOrCancel 的实现):

Future<void> thunk(dynamic value) {
  return;
}
final TickerFuture ticker = animationController.forward();
await ticker.onCancel.then(thunk, onError: thunk); // <- This resolves even if the ticker is canceled and the tests are not stuck anymore.

【讨论】:

    【解决方案2】:

    而不是await tester.pump(new Duration(milliseconds: 3000)); 尝试等待tester.pumpAndSettle();

    这种类型的泵等待动画结束,然后再泵帧。

    【讨论】:

      猜你喜欢
      • 2021-06-27
      • 1970-01-01
      • 2017-09-05
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多