使用Future.delayed时测试中断 [英] Test breaks when using Future.delayed

查看:297
本文介绍了使用Future.delayed时测试中断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了 Future.delayed 来显示使用以下代码在1秒钟内创建一个FAB:

I have used a Future.delayed to show a FAB in 1 second using this code:

Future.delayed(const Duration(seconds: 1), () {
  setState(() {
    _showFab = true;
  });
});

现在,最基本的烟雾测试已停止工作:

Now the most basic smoke test has stopped working:

void main() {
  testWidgets('smoke test', (WidgetTester tester) async {
    await tester.pumpWidget(MyApp());

    expect(find.byType(MyHomePage), findsOneWidget);
  });
}

这是错误消息:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following assertion was thrown running a test:
A Timer is still pending even after the widget tree was disposed.
'package:flutter_test/src/binding.dart': Failed assertion: line 933 pos 7:
'_currentFakeAsync.nonPeriodicTimerCount == 0'    import 'dart:async';

这里是所有使用的代码:

Here is all the code used:

import 'package:flutter/material.dart';
import 'dart:async';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _showFab = false;

  @override
  Widget build(BuildContext context) {
    Future.delayed(const Duration(seconds: 1), () {
      setState(() {
        _showFab = true;
      });
    });

    return Scaffold(
      floatingActionButton: AnimatedOpacity(
        opacity: _showFab ? 1.0 : 0.0,
        duration: Duration(milliseconds: 1400),
        child: FloatingActionButton(
          onPressed: null,
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

如何更改单元测试以进行测试通过?

How can I change the unit test to make the test pass?

推荐答案

您需要给测试人员足够的时间来处理您计划的所有异步调用,并尝试更改烟雾测试到这样的东西:

You need to give the tester enough time to process all the async calls you have scheduled, try change your smoke test to something like this:

void main() {
    testWidgets('smoke test', (WidgetTester tester) async {
    await tester.pumpWidget(MyApp());
    // Since you wait 1 second to start the animation and another 1.4 to complete it
    await tester.pump(Duration(seconds: 3));

    expect(find.byType(MyHomePage), findsOneWidget);
  });
}

您还需要移动 Future.delayed build()方法中删除,因为每次调用 setState()<时,这都会导致循环行为/ code>再次调用 build(),像这样更改状态:

You will also need to move the Future.delayed out of the build() method, because this is causing a cyclic behaviour, every time you call setState() the build() is called again, change your state like that:

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _showFab = false;

  @override
  void initState() {
    Future.delayed(const Duration(seconds: 1), () {
      setState(() {
        _showFab = true;
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: AnimatedOpacity(
        opacity: _showFab ? 1.0 : 0.0,
        duration: Duration(milliseconds: 1400),
        child: FloatingActionButton(
          onPressed: null,
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

这篇关于使用Future.delayed时测试中断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆