dart - Flutter 小部件测试 : StreamBuilder snapshot has

我正在尝试为使用 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/

相关文章:

firebase - Flutter - firebase_auth updateProfile 方

flutter - 加载数据时制作骨架屏幕的最简单方法

dart - 我可以在未来的构建器上使用多种方法吗?

flutter - 内置值对象的 setter 是什么

flutter - Sizedbox 与填充列和行中的距离

java - flutter 中是否有任何类可以像处理程序一样工作?

dart - Flutter:创建时间线 UI

dart - 如何为 Flutter 应用绘制折线图?

dart - 在 Flutter 中从文件中读取二维码

dart - Dart 中的类型定义