Home > Net >  Flutter Unit Test with Future.then
Flutter Unit Test with Future.then

Time:02-19

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

CodePudding user response:

  1. Future<T>.catchError expects a callback that returns a Future<T>.

  2. 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'));
  • Related