Flutter:测试未来的构建者

时间:2018-10-15 09:27:10

标签: testing dart flutter future

我想测试一个具有Future构建器的函数。功能是:

     Widget loadWidget() {
        return new FutureBuilder(
            future: getData(),
            builder: (BuildContext context, AsyncSnapshot<double> snapshot) {
              if (snapshot.hasData) {
                double content = snapshot.data;
              return new Container(...)
           } else {
            return new Center(
              child: CircularProgressIndicator(),
            );

我尝试编写的测试是这样的:

testWidgets("should return a container",
      (WidgetTester tester) async {
    await tester.pumpWidget(
        StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
      return MaterialApp(
          home: Material(
              child: Scaffold(
                  body:loadWidget());
    }));

    expect(find.byType(Container), findsOneWidget);

getData()函数似乎可以正常工作,所以我认为我的问题可能是我不知道如何使用AsyncSnapshot处理。

1 个答案:

答案 0 :(得分:0)

如果有人绊倒这个问题并像我一样寻找答案,我想分享一个可能的解决方案:

Completer<T> completer;
// ...
Widget loadWidget() {
  return new FutureBuilder(
    // substitute getData() here with the completer's Future
    future: completer.future,
    builder: (BuildContext context, AsyncSnapshot<double> snapshot) {
      if (snapshot.hasData) {
        double content = snapshot.data;
        return new Container(...)
      } else {
        return new Center(
          child: CircularProgressIndicator(),
        );
      }
    }
  );
// ...
testWidgets("should return a container", (WidgetTester tester) async {
  completer = Completer<T>(); // initialize Completer here!
  await tester.pumpWidget(
    StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
      return MaterialApp(
        home: Material(
          child: Scaffold(
            body: loadWidget()
          )
        )
      );
    }
  );
  // Interesting part comes here:
  // you can provide a Future or some piece of data
  // as parameter of the complete method
  completer.complete(getData()); // this "completes" (resolves) the future and returns the data you provided
  await tester.pump(Duration.zero); // still necessary
  expect(find.byType(Container), findsOneWidget); // should succeed now
});

您应将Future包裹在Completer中,然后手动完成Future。看看https://chromium.googlesource.com/external/github.com/flutter/flutter/+/v0.3.3/packages/flutter/test/widgets/async_test.dart。这是我从那里拿来的。 由于我对Flutter相当陌生,所以我真的不知道为什么必须使用completer方法初始化testWidgets。也许与testWidgets的范围有关。