Prajval Prabhakar
Prajval Prabhakar

Reputation: 313

Check method that returns a future for error

I want to check the error scenario. I want to check if catch error part is executed and an exception is returned when that happens. The exception being thrown is a custom exception (and in the future I would like to check the type and the value of the member variables of the exception).

What is the correct way to do this?

Here is the test :

test('should return error if fetching questions fails', () async {
      MockClient client = MockClient();
      GetIt.instance.registerSingleton<Client>(client);

      when(client.get(GET_QUESTIONS_FOR_USER))
          .thenAnswer((_) async => Future.error('error'));

      expect(QuestionsRepository().getQuestions(),
          throwsA(isInstanceOf<GenericError>()));

      verify(client.get(GET_QUESTIONS_FOR_USER)).called(1);
      verifyNoMoreInteractions(client);
    });

Here is the method that is being tested :

Future<List<QuestionTree>> getQuestions() async {
    return await client.get(GET_QUESTIONS_FOR_USER).then((response) {
      return _composeQuestionsList(
          DiveQuestionsList.fromJson(json.decode(response.body)));
    }).catchError((error) {
      return Future.error(GenericError('Error' + error.toString()));
    });
  }

And this is the stack trace :

package:dive/repository/questions_repo.dart        QuestionsRepository.getQuestions
===== asynchronous gap ===========================
package:test_api                                   expect
package:flutter_test/src/widget_tester.dart 348:3  expect
test/repository/questions_repo_test.dart 47:7      main.<fn>.<fn>
test/repository/questions_repo_test.dart 40:61     main.<fn>.<fn>
GenericError: Errorerror
dart:async                                         new Future.error
package:dive/repository/questions_repo.dart 22:21  QuestionsRepository.getQuestions.<fn>
===== asynchronous gap ===========================
dart:async                                         Future.catchError
package:dive/repository/questions_repo.dart 20:8   QuestionsRepository.getQuestions
test/repository/questions_repo_test.dart 47:36     main.<fn>.<fn>
test/repository/questions_repo_test.dart 40:61     main.<fn>.<fn>

Expected: throws <Instance of 'GenericError'>
  Actual: <Instance of 'Future<List<QuestionTree>>'>
   Which: threw _TypeError:<type 'Future<dynamic>' is not a subtype of type 'FutureOr<List<QuestionTree>>'>
          stack package:test_api                                   expect
                package:flutter_test/src/widget_tester.dart 348:3  expect
                test/repository/questions_repo_test.dart 47:7      main.<fn>.<fn>
                test/repository/questions_repo_test.dart 40:61     main.<fn>.<fn>

Upvotes: 0

Views: 459

Answers (1)

Claudio Redi
Claudio Redi

Reputation: 68400

You're mixing async and sync calls in getQuestions. In order to return a future await the call to get instead of using then

Future<List<QuestionTree>> getQuestions() async {
    var response = await client.get(GET_QUESTIONS_FOR_USER);

    if (response.statusCode == 200) {
        return _composeQuestionsList(
            DiveQuestionsList.fromJson(json.decode(response.body)));
    } else {
        // YOUR EXCEPTION GENERATION CODE HERE
    }
}

Upvotes: 1

Related Questions