Search code examples
flutter-test

How to test async exception?


I would like to figure out how to test that a widget throws an async exception.

Exception, that is created on the widget's initState:

  Future<void> _asyncError() async =>
      Future.delayed(Duration(microseconds: 1), () => throw FaultRoots.async);

The test, that does not detect the exception and then throws it:

            try {
              await tester.pumpWidget(widget);
              await tester.pumpAndSettle();

  
              expect(tester.takeException(), isNotNull);
              expect(tester.takeException().toString(), contains(p.route));
            } catch (ex) {
              print(ex.toString());
            }

Exception:

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following message was thrown running a test:
/fault/async

When the exception was thrown, this was the stack:
#0      _FaultPageState._asyncError.<anonymous closure> (package:flutter_firebase_hello/pages/fault_page.dart:26:55)
#8      FakeTimer._fire (package:fake_async/fake_async.dart:316:16)
#9      FakeAsync._fireTimersWhile (package:fake_async/fake_async.dart:240:13)
#10     FakeAsync.elapse (package:fake_async/fake_async.dart:137:5)
#11     AutomatedTestWidgetsFlutterBinding.pump.<anonymous closure> (package:flutter_test/src/binding.dart:965:28)
#14     TestAsyncUtils.guard (package:flutter_test/src/test_async_utils.dart:72:41)
#15     AutomatedTestWidgetsFlutterBinding.pump (package:flutter_test/src/binding.dart:961:27)
#16     WidgetTester.pumpAndSettle.<anonymous closure> (package:flutter_test/src/widget_tester.dart:640:23)
<asynchronous suspension>
<asynchronous suspension>
(elided 10 frames from dart:async and package:stack_trace)

Solution

  • Async exceptions can be caught by runZonedGuarded:

    await runZonedGuarded(() async {
      await tester.pumpWidget(makeTestable(widget));
      await tester.pumpAndSettle();
    }, (error, stack) {
      expectSync(error, isNotNull);
      print("Exception happened: " + error.toString())
      // More error validation ...
    });