我正在尝试为使用的窗口小部件编写窗口小部件测试StreamBuilder。在构建器中,我返回一个CircularProgressIndicatorif snapshot.hasDatais false,否则返回一个ListView窗口小部件。
在我的测试中,我创建了一个,StreamController并向其中添加了一个元素。当我运行测试时,我希望看到snapshot.hasData= true,但是相反,它false可以看到connectionStateis waiting。所以我的测试失败了。
不知何故,似乎第一个元素并未从流中拉出,并且连接仍保持waiting状态。我不确定自己在做什么错。
这是我的小部件测试:
testWidgets('Job item pressed - shows edit job page',
(WidgetTester tester) async {
StreamController<List<Job>> controller =
StreamController<List<Job>>.broadcast(sync: true);
Job job = Job(id: '0', createdAt: 0, jobName: 'Dart');
controller.add([job]);
final page = JobsPage(
jobsStream: controller.stream,
);
MockRouter mockRouter = MockRouter();
await tester.pumpWidget(makeTestableWidget(
child: page,
auth: MockAuth(),
database: MockDatabase(),
router: mockRouter,
));
Finder waiting = find.byType(CircularProgressIndicator);
expect(waiting, findsNothing);
Finder placeholder = find.byType(PlaceholderContent);
expect(placeholder, findsNothing);
Finder item = find.byKey(Key('jobListItem-${job.id}'));
expect(item, findsOneWidget);
await controller.close();
});
Run Code Online (Sandbox Code Playgroud)
这是我的小部件代码:
Widget _buildContent(BuildContext context) {
return StreamBuilder<List<Job>>(
stream: jobsStream,
builder: (context, snapshot) {
return ListItemsBuilder(
snapshot: snapshot,
itemBuilder: (BuildContext context, Job job) {
return JobListItem(
key: Key('jobListItem-${job.id}'),
title: job.jobName, // TODO: This be null?
onTap: () => _select(context, job),
);
},
);
},
);
}
Run Code Online (Sandbox Code Playgroud)
和ListItemsBuilder:
typedef Widget ItemWidgetBuilder<T>(BuildContext context, T item);
class ListItemsBuilder<T> extends StatelessWidget {
ListItemsBuilder({this.snapshot, this.itemBuilder});
final AsyncSnapshot<List<T>> snapshot;
final ItemWidgetBuilder<T> itemBuilder;
@override
Widget build(BuildContext context) {
// prints "waiting"
print('${snapshot.connectionState.toString()}');
if (snapshot.hasData) {
final items = snapshot.data;
if (items.length > 0) {
return _buildList(items);
} else {
return PlaceholderContent();
}
} else if (snapshot.error != null) {
print('${snapshot.error}');
return PlaceholderContent(
title: 'Something went wrong',
message: 'Can\'t load entries right now',
);
} else {
return Center(child: CircularProgressIndicator());
}
}
Widget _buildList(List<T> items) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return itemBuilder(context, items[index]);
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用a StreamController.broadcast(sync: true)代替了simple StreamController,但是没有什么区别。
另外,任何其他pump()和pumpAndSettle()呼叫都不会产生任何影响。
有任何想法吗?
解
使用 await tester.pump(Duration.zero);
完整的测试代码:
testWidgets('Job item pressed - shows edit job page',
(WidgetTester tester) async {
StreamController<List<Job>> controller = StreamController<List<Job>>();
Job job = Job(id: '0', createdAt: 0, jobName: 'Dart');
controller.add([job]);
final page = JobsPage(
jobsStream: controller.stream,
);
MockRouter mockRouter = MockRouter();
await tester.pumpWidget(makeTestableWidget(
child: page,
auth: MockAuth(),
database: MockDatabase(),
router: mockRouter,
));
// this will cause the stream to emit the first event
await tester.pump(Duration.zero);
Finder waiting = find.byType(CircularProgressIndicator);
expect(waiting, findsNothing);
Finder placeholder = find.byType(PlaceholderContent);
expect(placeholder, findsNothing);
Finder item = find.byKey(Key('jobListItem-${job.id}'));
expect(item, findsOneWidget);
await controller.close();
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2532 次 |
| 最近记录: |