Reputation: 98
I seem to be unable to test if an exception is thrown in Flutter. I would expect the test to pass if an exception is thrown considering I expect an Exception.
What I have tried:
import 'package:flutter_test/flutter_test.dart';
void main() {
test('Range error test', () {
expect(throw RangeError(""), throwsA(RangeError("")));
});
test('Range error test', () {
expect(throw RangeError(""), throwsA(RangeError));
});
test('Range error test', () {
expect(throw RangeError(""), throwsRangeError);
});
test('ConcurrentModificationError error test', () {
expect(throw ConcurrentModificationError(""), throwsA(ConcurrentModificationError));
});
test('NumberFormat error test', () {
expect(int.parse("sdffg"), throwsA(FormatException));
});
test('NumberFormat error test', () {
expect(int.parse("sdffg"), throwsFormatException);
});
test('Range error test', () {
var list = [];
expect(list[1], throwsRangeError);
});
test('Range error test', () {
var list = [];
expect(list[1], throwsA(RangeError));
});
}
dependencies in pubspec.yaml:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
test:
Errors after running them in Android Studio (I get the same errors when running from cli):
Upvotes: 5
Views: 2699
Reputation: 8427
Let's take one of your examples:
expect(throw RangeError(""), throwsA(RangeError("")));
There are a few problems here.
Since throw RangeError("")
is part of a larger expression, it is evaluated before the whole expression does, so you can't hope for expect()
to be evaluated if throw RangeError("")
breaks the flow.
To make this explanation more didactic, imagine we extracted the arguments into variables:
final neverAssigned = throw RangeError("");
final throwsRangeError = throwsA(RangeError(""));
expect(neverAssigned, throwsRangeError);
As you may have realized, we never reach expect()
because the program already throws at the first line.
To solve this problem, expect()
requires you to pass a function that potentially throws. It will check that it is a function, wrap the call in try-catch and check whether the error thrown is what you expect.
We should end up with something like this:
expect(() => throw RangeError(""), throwsA(RangeError("")));
However, this doesn't work as well, since errors in general don't implement operator ==
and hashCode
, so RangeError("") == RangeError("")
gives you false
. This means it's not that simple to check whether the error thrown is exactly what you expect.
Instead, you should check only the type with something like throwsA(isA<RangeError>())
, or check the message with having
.
Upvotes: 6