Flutter Unit Test with Future.then
274
-
Future<T>.catchError
expects a callback that returns aFuture<T>
. -
However,
Future.catchError
is confusing to use, and it'd be better to avoid it entirely:
try {
await A(bmock).doSomething();
fail('doSomething did not throw');
} catch (e) {
expect(e, 'error');
}
or you can use expectLater
:
await expectLater(A(bmock).doSomething(), throwsA('error'));
Author by
0xPixelfrost
Updated on January 03, 2023Comments
-
0xPixelfrost over 1 year
I want to write a flutter unit test, where a future maps a result to something different and returns the new result again as future, like:
Future<String> invoke() => class.doSomething().then((value) => map(value));
The sample method "invoke()" should return the mapped value.
The positive test, returning the mapped value, is working. (test1 in sample below)The negative test, returning an Future.error, fails with this error (test 2 in sample below):
Invalid argument(s) (onError): The error handler of Future.catchError must return a value of the future's type
Does anybody know how to improve the test so i can test the error case like described in test2:
import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:test/test.dart'; import 'test_test.mocks.dart'; class A { final B b; A(this.b); Future<String> doSomething() => b.doSomething().then((value) => "mappedResult"); } class B { Future<int> doSomething() => Future.delayed(const Duration(seconds: 1)); } @GenerateMocks([B]) void main() { final bmock = MockB(); test('test1', () async { when(bmock.doSomething()).thenAnswer((_) => Future.value(1)); var result = await A(bmock).doSomething(); expect(result, "mappedResult"); }); test('test2', () async { when(bmock.doSomething()).thenAnswer((_) => Future.error("error")); A(bmock).doSomething().catchError((error) { expect(error, "error"); }); }); }
Versions:
Flutter 2.10.1 mockito: ^5.0.17 test: ^1.17.12