我正在为一个使用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测试?
2条答案
按热度按时间y0u0uwnf1#
通过mockito可以实现真正的bloc测试。您可以为DB调用创建存根。当该函数完成时,您可以使用
unitlCalled()
ct3nt3jp2#
结果证明我的整体设置是正确的,但
Floor
包要求您在需要await
一些async
Floor
操作时将这一行添加到测试中:字符串
整个代码现在看起来像这样:
型
我在他们的example project的单元测试中发现了这个信息。