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.