gpt4 book ai didi

dart - Flutter 小部件测试 : StreamBuilder snapshot has connectionState = waiting with a non-empty Stream

转载 作者:IT老高 更新时间:2023-10-28 12:40:47 27 4
gpt4 key购买 nike

我正在尝试为使用 StreamBuilder 的小部件编写小部件测试。在构建器中,如果 snapshot.hasDatafalse,则返回 CircularProgressIndicator,否则返回小部件的 ListView .

在我的测试中,我创建了一个 StreamController 并向其中添加了一个元素。当我运行测试时,我希望看到 snapshot.hasData = true,但它是 false,我可以看到 >connectionStatewaiting。所以我的测试失败了。

不知何故,第一个元素似乎没有从流中拉出,并且连接保持在 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();
});

这是我的小部件代码:

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),
);
},
);
},
);
}

还有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]);
},
);
}
}

我尝试使用 StreamController.broadcast(sync: true) 而不是简单的 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();
});

关于dart - Flutter 小部件测试 : StreamBuilder snapshot has connectionState = waiting with a non-empty Stream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51786850/

27 4 0