How to unit-test timeout in Flutter?

Viewed 201

I have a facade function that reloads the current firebase user and returns it. The thing is that the user reloading part has a timeout and it needs to be tested.

Function:

Future<Option<User>> getSignedInUser() async {
    // Reload currentUser if possible
    // it mustn't throw [TimeoutException] for whole function,
    // this is what this try/catch does
    try {
      await reloadCurrentUser().timeout(const Duration(seconds: 20));
    } catch (e) {
      log(e.toString(), name: TAG);
    }
    return optionOf(_auth.currentUser);
  }

reloadCurrentUser() function:

Future<Either<AuthFailure, Unit>> reloadCurrentUser() async {
    try {
      await _auth.currentUser?.reload();
      return right(unit);
    } catch (e) {
      log(e.toString(), name: TAG);
      return left(const AuthFailure.userReloadingError());
    }
  }

The question is how to test reloadCurrentUser() timeout? I'm trying to throw a TimeoutException when this function is called, but then it throws an error for the whole test.

Current Test function:

test(
        'Reaches timeout when reloading currentUser, '
        'throws TimeoutException, but function continues '
        'and returns optionOf currentUser', () async {
      reset(fakeFirebaseAuth);
      reset(fakeFacebookAuth);
      reset(fakeGoogleSignIn);

      final currentUser = FakeUser();

      // It says that currentUser exists and *IS* authenticated
      when(() => fakeFirebaseAuth.currentUser).thenReturn(currentUser);
      when(() => firebaseAuthFacade.reloadCurrentUser())
          .thenThrow(TimeoutException('timeout', const Duration(seconds: 20)));

      final result = await firebaseAuthFacade.getSignedInUser();

      expect(result, isA<Some<User>>());
    });

Maybe it's better to remove timeout and use some connectivity package to ensure that the user has a network connection and only then reload the current user?

For testing I'm using mocktail package.

0 Answers
Related