flutter 地板:如何进行真正的恒温检测

ccgok5k5  于 6个月前  发布在  Flutter
关注(0)|答案(2)|浏览(59)

我正在为一个使用Floor数据库来存储和检索数据的Widget编写测试。测试用例使用inMemory数据库而不是模拟数据库。这意味着测试中所有的数据操作都是真正的async。我面临的问题是,我的async方法调用在测试完成后很好地完成了。
我有以下单元测试:

testWidgets('test add new set', (WidgetTester tester) async {
  await pumpApp(tester, exercisesProvider, setRepository, exerciseRepository);
  await tester.runAsync(() async {
    var bench = find.text('Bench Press');
    expect(bench, findsOneWidget);
    await tester.tap(bench);
    await tester.pump();
    await tester.pump();
    // Should be found if content is loaded
    expect(find.text('Clear'), findsOneWidget);
  });

字符串
测试失败,输出如下:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown while running async test code:
Expected: exactly one matching node in the widget tree
  Actual: _TextFinder:<zero widgets with text "Clear" (ignoring offstage widgets)>
   Which: means none were found but one was expected
...
The exception was caught asynchronously.
════════════════════════════════════════════════════════════════════════════════════════════════════
FETCH COMPLETED


测试中的widget:

@override
Widget build(BuildContext context) {
  // This async method is executed too late
  Provider.of<SetProvider>(context, listen: false)
      .fetchGroupedSetsByExercise(widget.selectedExercise.id!);

  return Column(
    children: [
      Expanded(
        child: Consumer<SetProvider>(builder: (context, setProvider, chil
          final groupedSets = setProvider.groupedSets;
          if (setProvider.groupedSetsState == IOState.loading ||
              setProvider.groupedSetsState == IOState.initial) {
            return ...;
          } else if (setProvider.groupedSetsState == IOState.error) {
            return ...;
          } else if (groupedSets.isEmpty) {
            return ...;
          }
          // Contains the clear button and more
          return buildSetList(groupedSets, setProvider);
        }),
      ),
    ],
  );


供应商:

Future<void> fetchGroupedSetsByExercise(int exerciseID,
    {bool? reverse}) async {
  groupedSets = groupSetsByDate(
      await fetchSetsByExercise(exerciseID, reverse: reverse));
  lastSetEntry = groupedSets.values.lastOrNull?.lastOrNull;
  groupedSetsState = IOState.success;
  notifyListeners();
  print("FETCH COMPLETED");
}


正如你在测试输出中看到的,fetchGroupedSetsByExercise总是在测试结束后执行。我知道你需要使用await来等待async函数完成,但是,我如何测试我的小部件?我的小部件跟踪获取状态本身(在groupedSetsState中),我不能await任何东西,而是提供者将在数据到达时通知小部件。
我也试过使用:

  • FutureBuilder
  • 等待多个pump呼叫
  • 等待pumpAndSettle
  • 删除tester.runAsync线路

结果都一样,测试失败,因为async方法执行得太晚了。我该如何编写真正的JavaScript测试?

y0u0uwnf

y0u0uwnf1#

通过mockito可以实现真正的bloc测试。您可以为DB调用创建存根。当该函数完成时,您可以使用
unitlCalled()

ct3nt3jp

ct3nt3jp2#

结果证明我的整体设置是正确的,但Floor包要求您在需要await一些asyncFloor操作时将这一行添加到测试中:

await Future<void>.delayed(const Duration(milliseconds: 100));

字符串
整个代码现在看起来像这样:

testWidgets('test add new set', (WidgetTester tester) async {
  await pumpApp(
      tester, exercisesProvider, setRepository, exerciseRepository,
      setProvider);
  await tester.runAsync(() async {
    var bench = find.text('Bench Press');
    expect(bench, findsOneWidget);
    await tester.tap(bench);
    await tester.pump();
    await Future<void>.delayed(const Duration(milliseconds: 100));
    await tester.pump();
    // Should be found if content is loaded
    expect(find.text('Clear'), findsOneWidget);


我在他们的example project的单元测试中发现了这个信息。

相关问题