[null-safety] remove mockito from network tests (#64284)
More work towards removal of mockito to facilitate strong null safety tests. #62886
This commit is contained in:
@@ -13,8 +13,8 @@ import 'dart:ui' show Codec, FrameInfo;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../flutter_test_alternative.dart' show Fake;
|
||||
import '../rendering/rendering_tester.dart';
|
||||
import 'image_data.dart';
|
||||
|
||||
@@ -25,10 +25,10 @@ void main() {
|
||||
return PaintingBinding.instance.instantiateImageCodec(bytes, cacheWidth: cacheWidth, cacheHeight: cacheHeight, allowUpscaling: allowUpscaling);
|
||||
};
|
||||
|
||||
_MockHttpClient httpClient;
|
||||
_FakeHttpClient httpClient;
|
||||
|
||||
setUp(() {
|
||||
httpClient = _MockHttpClient();
|
||||
httpClient = _FakeHttpClient();
|
||||
debugNetworkImageHttpClientProvider = () => httpClient;
|
||||
});
|
||||
|
||||
@@ -42,11 +42,7 @@ void main() {
|
||||
final int errorStatusCode = HttpStatus.notFound;
|
||||
const String requestUrl = 'foo-url';
|
||||
|
||||
final _MockHttpClientRequest request = _MockHttpClientRequest();
|
||||
final _MockHttpClientResponse response = _MockHttpClientResponse();
|
||||
when(httpClient.getUrl(any)).thenAnswer((_) => Future<HttpClientRequest>.value(request));
|
||||
when(request.close()).thenAnswer((_) => Future<HttpClientResponse>.value(response));
|
||||
when(response.statusCode).thenReturn(errorStatusCode);
|
||||
httpClient.request.response.statusCode = errorStatusCode;
|
||||
|
||||
final Completer<dynamic> caughtError = Completer<dynamic>();
|
||||
|
||||
@@ -84,7 +80,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('Uses the HttpClient provided by debugNetworkImageHttpClientProvider if set', () async {
|
||||
when(httpClient.getUrl(any)).thenThrow('client1');
|
||||
httpClient.thrownError = 'client1';
|
||||
final List<dynamic> capturedErrors = <dynamic>[];
|
||||
|
||||
Future<void> loadNetworkImage() async {
|
||||
@@ -101,15 +97,15 @@ void main() {
|
||||
|
||||
await loadNetworkImage();
|
||||
expect(capturedErrors, <dynamic>['client1']);
|
||||
final _MockHttpClient client2 = _MockHttpClient();
|
||||
when(client2.getUrl(any)).thenThrow('client2');
|
||||
final _FakeHttpClient client2 = _FakeHttpClient();
|
||||
client2.thrownError = 'client2';
|
||||
debugNetworkImageHttpClientProvider = () => client2;
|
||||
await loadNetworkImage();
|
||||
expect(capturedErrors, <dynamic>['client1', 'client2']);
|
||||
}, skip: isBrowser); // Browser implementation does not use HTTP client but an <img> tag.
|
||||
|
||||
test('Propagates http client errors during resolve()', () async {
|
||||
when(httpClient.getUrl(any)).thenThrow(Error());
|
||||
httpClient.thrownError = Error();
|
||||
bool uncaught = false;
|
||||
|
||||
final FlutterExceptionHandler oldError = FlutterError.onError;
|
||||
@@ -141,30 +137,11 @@ void main() {
|
||||
Uint8List.fromList(kTransparentImage.skip(offset).take(chunkSize).toList()),
|
||||
];
|
||||
final Completer<void> imageAvailable = Completer<void>();
|
||||
final _MockHttpClientRequest request = _MockHttpClientRequest();
|
||||
final _MockHttpClientResponse response = _MockHttpClientResponse();
|
||||
when(httpClient.getUrl(any)).thenAnswer((_) => Future<HttpClientRequest>.value(request));
|
||||
when(request.close()).thenAnswer((_) => Future<HttpClientResponse>.value(response));
|
||||
when(response.statusCode).thenReturn(HttpStatus.ok);
|
||||
when(response.contentLength).thenReturn(kTransparentImage.length);
|
||||
when(response.listen(
|
||||
any,
|
||||
onDone: anyNamed('onDone'),
|
||||
onError: anyNamed('onError'),
|
||||
cancelOnError: anyNamed('cancelOnError'),
|
||||
)).thenAnswer((Invocation invocation) {
|
||||
final void Function(List<int>) onData = invocation.positionalArguments[0] as void Function(List<int>);
|
||||
final void Function(Object) onError = invocation.namedArguments[#onError] as void Function(Object);
|
||||
final VoidCallback onDone = invocation.namedArguments[#onDone] as VoidCallback;
|
||||
final bool cancelOnError = invocation.namedArguments[#cancelOnError] as bool;
|
||||
|
||||
return Stream<Uint8List>.fromIterable(chunks).listen(
|
||||
onData,
|
||||
onDone: onDone,
|
||||
onError: onError,
|
||||
cancelOnError: cancelOnError,
|
||||
);
|
||||
});
|
||||
httpClient.request.response
|
||||
..statusCode = HttpStatus.ok
|
||||
..contentLength = kTransparentImage.length
|
||||
..content = chunks;
|
||||
|
||||
final ImageProvider imageProvider = NetworkImage(nonconst('foo'));
|
||||
final ImageStream result = imageProvider.resolve(ImageConfiguration.empty);
|
||||
@@ -189,11 +166,10 @@ void main() {
|
||||
}, skip: isBrowser); // Browser loads images through <img> not Http.
|
||||
|
||||
test('NetworkImage is evicted from cache on SocketException', () async {
|
||||
final _MockHttpClient mockHttpClient = _MockHttpClient();
|
||||
when(mockHttpClient.getUrl(any)).thenAnswer((_) => throw const SocketException('test exception'));
|
||||
final _FakeHttpClient mockHttpClient = _FakeHttpClient();
|
||||
mockHttpClient.thrownError = const SocketException('test exception');
|
||||
debugNetworkImageHttpClientProvider = () => mockHttpClient;
|
||||
|
||||
|
||||
final ImageProvider imageProvider = NetworkImage(nonconst('testing.url'));
|
||||
expect(imageCache.pendingImageCount, 0);
|
||||
expect(imageCache.statusForKey(imageProvider).untracked, true);
|
||||
@@ -232,30 +208,10 @@ void main() {
|
||||
for (int offset = 0; offset < kTransparentImage.length; offset += chunkSize)
|
||||
Uint8List.fromList(kTransparentImage.skip(offset).take(chunkSize).toList()),
|
||||
];
|
||||
final _MockHttpClientRequest request = _MockHttpClientRequest();
|
||||
final _MockHttpClientResponse response = _MockHttpClientResponse();
|
||||
when(httpClient.getUrl(any)).thenAnswer((_) => Future<HttpClientRequest>.value(request));
|
||||
when(request.close()).thenAnswer((_) => Future<HttpClientResponse>.value(response));
|
||||
when(response.statusCode).thenReturn(HttpStatus.ok);
|
||||
when(response.contentLength).thenReturn(kTransparentImage.length);
|
||||
when(response.listen(
|
||||
any,
|
||||
onDone: anyNamed('onDone'),
|
||||
onError: anyNamed('onError'),
|
||||
cancelOnError: anyNamed('cancelOnError'),
|
||||
)).thenAnswer((Invocation invocation) {
|
||||
final void Function(List<int>) onData = invocation.positionalArguments[0] as void Function(List<int>);
|
||||
final void Function(Object) onError = invocation.namedArguments[#onError] as void Function(Object);
|
||||
final VoidCallback onDone = invocation.namedArguments[#onDone] as VoidCallback;
|
||||
final bool cancelOnError = invocation.namedArguments[#cancelOnError] as bool;
|
||||
|
||||
return Stream<Uint8List>.fromIterable(chunks).listen(
|
||||
onData,
|
||||
onDone: onDone,
|
||||
onError: onError,
|
||||
cancelOnError: cancelOnError,
|
||||
);
|
||||
});
|
||||
httpClient.request.response
|
||||
..statusCode = HttpStatus.ok
|
||||
..contentLength = kTransparentImage.length
|
||||
..content = chunks;
|
||||
|
||||
const NetworkImage provider = NetworkImage(url);
|
||||
|
||||
@@ -263,12 +219,51 @@ void main() {
|
||||
|
||||
expect(completer.debugLabel, url);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
class _MockHttpClient extends Mock implements HttpClient {}
|
||||
class _MockHttpClientRequest extends Mock implements HttpClientRequest {}
|
||||
class _MockHttpClientResponse extends Mock implements HttpClientResponse {}
|
||||
class _FakeHttpClient extends Fake implements HttpClient {
|
||||
final _FakeHttpClientRequest request = _FakeHttpClientRequest();
|
||||
dynamic thrownError;
|
||||
|
||||
@override
|
||||
Future<HttpClientRequest> getUrl(Uri url) async {
|
||||
if (thrownError != null) {
|
||||
throw thrownError;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
}
|
||||
class _FakeHttpClientRequest extends Fake implements HttpClientRequest {
|
||||
final _FakeHttpClientResponse response = _FakeHttpClientResponse();
|
||||
|
||||
@override
|
||||
Future<HttpClientResponse> close() async {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
class _FakeHttpClientResponse extends Fake implements HttpClientResponse {
|
||||
@override
|
||||
int statusCode = HttpStatus.ok;
|
||||
|
||||
@override
|
||||
int contentLength = 0;
|
||||
|
||||
@override
|
||||
HttpClientResponseCompressionState get compressionState => HttpClientResponseCompressionState.notCompressed;
|
||||
|
||||
List<List<int>> content;
|
||||
|
||||
@override
|
||||
StreamSubscription<List<int>> listen(void Function(List<int> event) onData, {Function onError, void Function() onDone, bool cancelOnError}) {
|
||||
return Stream<List<int>>.fromIterable(content).listen(
|
||||
onData,
|
||||
onDone: onDone,
|
||||
onError: onError,
|
||||
cancelOnError: cancelOnError,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FakeCodec implements Codec {
|
||||
@override
|
||||
|
||||
Reference in New Issue
Block a user