Using [thenThrow] and closure in [expect] break [verify] method
Describe the bug
Using thenThrow and closure in expect to test throwing will break verify method.
Only the first mock function - verify(() => http.get(any())).called(1); in this case - is verified.
To Reproduce Run below test
Code
// Data Source
class RemoteDataSource {
const RemoteDataSource({
required Client http,
}) : _http = http;
final Client _http;
Future<void> getSomething() async {
final uri = Uri.https('example.com', '/path');
await _http.get(uri);
await _http.post(uri);
await _http.put(uri);
}
}
// Test
class MockHttpClient extends Mock implements Client {}
void main() {
late MockHttpClient http;
late RemoteDataSource remoteDataSource;
setUp(() async {
registerFallbackValue(Uri());
http = MockHttpClient();
remoteDataSource = RemoteDataSource(http: http);
});
group('getSomething', () {
test('post should called once', () {
when(
() => http.get(any()),
).thenAnswer((invocation) async => Response('', 200));
when(
() => http.post(any()),
).thenAnswer((invocation) async => Response('', 200));
when(() => http.put(any())).thenThrow(Exception());
expect(() => remoteDataSource.getSomething(), throwsA(isA<Exception>()));
verify(() => http.post(any())).called(1);
});
});
}
Expected behavior
verify(() => http.post(any())).called(1); should passed.
Logs
No matching calls. All calls: MockHttpClient.get(https://example.com/path, {headers: null})
(If you called `verify(...).called(0);`, please instead use `verifyNever(...);`.)
Additional context Dart: 3.4.3 Flutter: 3.22.2 mocktail: 1.0.4 http: 1.2.2
I encountered a similar problem when mocking the same instance twice for different asynchronous method calls. The first call returned a simple value, and the second threw an exception. I expected the mock to remember the last call, but it didn't.
Here's a minimal reproducible example
https://github.com/BrayanCaro/mocktail_missing_last_stub_issue_247