14

How do I go about making sure the ui (widget) throws an exception during widget testing in Flutter. Here is my code that does not work:

expect(
  () => tester.tap(find.byIcon(Icons.send)),
  throwsA(const TypeMatcher<UnrecognizedTermException>()),
);

It fails with the following error

...
Expected: throws <Instance of 'TypeMatcher<UnrecognizedTermException>'>
  Actual: <Closure: () => Future<void>>
   Which: returned a Future that emitted <null>

OR......should I be testing how the UI handles an exception by looking for error messages, etc??

xpeldev
  • 1,812
  • 2
  • 12
  • 23

2 Answers2

10

To catch exceptions thrown in a flutter test, use WidgetTester.takeException. This returns the last exception caught by the framework.

await tester.tap(find.byIcon(Icons.send));
expect(tester.takeException(), isInstanceOf<UnrecognizedTermException>());

You also don't need a throwsA matcher, since it is not being thrown from the method.

Jonah Williams
  • 20,499
  • 6
  • 65
  • 53
  • actually ```expect(tester.takeException(), isInstanceOf());``` worked well! Thank you – xpeldev Jan 18 '19 at 22:12
  • You got me thinking: "...returns the last exception caught by the framework". I would rather have my logic catch it for better design. This is valuable nonetheless. ill accept as answer in 4 min – xpeldev Jan 18 '19 at 22:15
  • 4
    Notice that this does not work in all situations. In some rare situations, you may want to override `FlutterError.onError` (and restore it after). – Rémi Rousselet Jan 18 '19 at 22:16
  • Darn!. I just ran into the FlutterError.onError issue. will post another question – xpeldev Jan 21 '19 at 16:54
  • 2
    Hey, what about exceptions raised in an async context? I'm having trouble trying to catch them in my test. – Fran Nov 06 '20 at 18:36
0

If you want to handle async error try wrapping your test with runZonedGuarded. If not then Widget.takeException should work

Ilya Maximencko
  • 411
  • 2
  • 15