【发布时间】:2019-10-29 05:11:27
【问题描述】:
我在对在 Future 期间引发异常的小部件进行小部件测试时遇到问题。
重现问题的代码
这是一个简单的测试小部件,它以非常简单的方式重现问题(感谢 Remi Rousselet 对问题的简化)。
testWidgets('This test should pass but fails', (tester) async {
final future = Future<void>.error(42);
await tester.pumpWidget(FutureBuilder(
future: future,
builder: (_, snapshot) {
return Container();
},
));
});
预期结果
我希望测试能够顺利完成。相反,它失败并出现以下错误:
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The number 42 was thrown running a test.
When the exception was thrown, this was the stack:
#2 main.<anonymous closure> (file:///C:/Projects/projet_65/mobile_app/test/ui/exception_test.dart:79:18)
#5 TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:0:0)
#8 TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:577:14)
#9 AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:993:24)
#15 AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:990:15)
#16 testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:106:22)
#17 Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:168:27)
#20 Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/declarer.dart:0:0)
#21 Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test_api/src/backend/invoker.dart:250:15)
#27 Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/backend/invoker.dart:399:21)
(elided 17 frames from class _FakeAsync, package dart:async, and package dart:async-patch)
The test description was:
This test should pass but fails
════════════════════════════════════════════════════════════════════════════════════════════════════
我的尝试
我已经尝试expect 错误,如果它不在Future 中,我会这样做:
expect(tester.takeException(), equals(42));
但该语句失败并出现以下错误
The following TestFailure object was thrown running a test (but after the test had completed):
Expected: 42
Actual: null
编辑:
@shb 答案对于暴露的情况是正确的。这是一个轻微的修改,可以打破它并返回初始错误。这种情况在实际应用中更容易发生(我就是这种情况)
testWidgets('This test should pass but fails', (tester) async {
Future future;
await tester.pumpWidget(
MaterialApp(
home: Row(
children: <Widget>[
FlatButton(
child: const Text('GO'),
onPressed: () { future = Future.error(42);},
),
FutureBuilder(
future: future,
builder: (_, snapshot) {
return Container();
},
),
],
),
));
await tester.tap(find.text('GO'));
});
注意:我自愿省略了@shb 提出的tester.runAsync 以匹配最初的问题,因为它在特定情况下不起作用
【问题讨论】:
-
(没关系,忽略我之前的cmets。)
-
@Muldec 如果将
tester.tap包裹在runAsync中会发生什么? -
@RémiRousselet 相同的错误加上一个新的
The following assertion was thrown running a test (but after the test had completed): 'package:flutter_test/src/binding.dart': Failed assertion: line 1020 pos 12: '_currentFakeAsync !=null': is not true.(意味着测试引发了两个错误)
标签: flutter error-handling dart flutter-test