我想测试一个具有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处理。
答案 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
的范围有关。