Home > Back-end >  Mock different answers and exceptions after several calls with Mocktail
Mock different answers and exceptions after several calls with Mocktail

Time:10-26

I was using mocktail for my unit testing and I could not find a way to throw an Exception on the first call but later, on the second call, answer with the right output.

I could find this solution for two different answers but this was not enough for testing exceptions thrown. So I needed to come up with a modified solution.

This is what I wanted to achieve. By the way, I was testing a connection retry with http get.

import 'package:http/http.dart' as http;
import 'package:mocktail/mocktail.dart';

class MockClient extends Mock implements http.Client {}

final mockClient = MockClient();

//First time fails, second one retrieves a result. This doesn't work on Mocktail
when(() => mockClient.get(Uri.parse(url)))
  .thenThrow(SocketException()) // Call 1
  .thenAnswer((_) => Future.value(http.Response("page content", 200)) // Call 2
);

CodePudding user response:

After trying different ideas, a possible solution was to store each answer inside of a List

import 'package:http/http.dart' as http;
import 'package:mocktail/mocktail.dart';

class MockClient extends Mock implements http.Client {}

final mockClient = MockClient();

final List<Future<http.Response> Function(Invocation)> answers = [
 (_) => throw SocketException(),
 (_) => Future.value(http.Response("page content", 200)),
];


when(() => mockClient.get(Uri.parse(url)))
  .thenAnswer((invocation) => answers.removeAt(0)(invocation));
// Calling answers.removeAt(0) without the lambda method returns the same answer on all of them

In this example Invocation is not used and checks only 2 consecutive calls. But that behavior can be extended from what you can see here.

I haven't tried this with Mockito but it should work in a similar way adapting the syntax.

  • Related