I can widget test Image.network using HttpOverrides and tried following code to test CachedNetworkImage with no success Is there anybody who tested this package already? I've also tried to use sqflite using setMockMethodCallHandler to MethodChannel('com.tekartik.sqflite') but just getDatabasesPath method get called what is the correct approach to test this package?
import 'dart:async';
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import '../unit_test/sqlcool.dart';
const List<int> kTransparentImage = <int>[
0x89,
0x50,
0x4E,
0x47,
0x0D,
0x0A,
0x1A,
0x0A,
0x00,
0x00,
0x00,
0x0D,
0x49,
0x48,
0x44,
0x52,
0x00,
0x00,
0x00,
0x01,
0x00,
0x00,
0x00,
0x01,
0x08,
0x06,
0x00,
0x00,
0x00,
0x1F,
0x15,
0xC4,
0x89,
0x00,
0x00,
0x00,
0x0A,
0x49,
0x44,
0x41,
0x54,
0x78,
0x9C,
0x63,
0x00,
0x01,
0x00,
0x00,
0x05,
0x00,
0x01,
0x0D,
0x0A,
0x2D,
0xB4,
0x00,
0x00,
0x00,
0x00,
0x49,
0x45,
0x4E,
0x44,
0xAE,
];
void main() async {
TestWidgetsFlutterBinding.ensureInitialized();
await setup();
final MockHttpClient client = MockHttpClient();
final MockHttpClientRequest request = MockHttpClientRequest();
final MockHttpClientResponse response = MockHttpClientResponse();
final MockHttpHeaders headers = MockHttpHeaders();
testWidgets('Headers', (WidgetTester tester) async {
HttpOverrides.runZoned<Future<void>>(() async {
// await tester.pumpWidget(Image.network(
// 'https://www.example.com/images/frame.png',
// headers: const <String, String>{'flutter': 'flutter'},
// ));
await tester.pumpWidget(CachedNetworkImage(
imageUrl: 'https://www.example.com/images/frame.png',
errorWidget: (context, err, o) {
print(
"===========>>>>> CachedNetworkImage error= $err <<<<=================");
}));
}, createHttpClient: (SecurityContext _) {
when(client.getUrl(any)).thenAnswer((invocation) {
print(
"================>>>>>> getUrl = ${invocation.positionalArguments} <<<<<===============");
return Future<HttpClientRequest>.value(request);
});
when(request.headers).thenReturn(headers);
when(request.close()).thenAnswer((invocation) {
print(
"================>>>>>> request.close = ${invocation.toString()} <<<<<===============");
return Future<HttpClientResponse>.value(response);
});
when(response.contentLength).thenReturn(kTransparentImage.length);
when(response.statusCode).thenReturn(HttpStatus.ok);
when(response.listen(any)).thenAnswer((Invocation invocation) {
final void Function(List<int>) onData =
invocation.positionalArguments[0] as void Function(List<int>);
print(
"================>>>>>> onData = ${onData} <<<<<===============");
final void Function() onDone =
invocation.namedArguments[#onDone] as void Function();
print(
"================>>>>>> onDone = ${onDone} <<<<<===============");
final void Function(Object, [StackTrace]) onError = invocation
.namedArguments[#onError] as void Function(Object, [StackTrace]);
final bool cancelOnError =
invocation.namedArguments[#cancelOnError] as bool;
return Stream<List<int>>.fromIterable(<List<int>>[kTransparentImage])
.listen(onData,
onDone: onDone, onError: onError, cancelOnError: cancelOnError);
});
return client;
});
}, skip: isBrowser);
}
class MockHttpClient extends Mock implements HttpClient {}
class MockHttpClientRequest extends Mock implements HttpClientRequest {}
class MockHttpClientResponse extends Mock implements HttpClientResponse {}
class MockHttpHeaders extends Mock implements HttpHeaders {}
Directory directory;
const MethodChannel channel = MethodChannel('com.tekartik.sqflite');
final List<MethodCall> log = <MethodCall>[];
bool setupDone = false;
Future<void> setup() async {
// WidgetsFlutterBinding.ensureInitialized();
if (setupDone) {
return;
}
directory = await Directory.systemTemp.createTemp();
String response;
channel.setMockMethodCallHandler((MethodCall methodCall) async {
print("METHOD CALL: $methodCall");
log.add(methodCall);
switch (methodCall.method) {
case "getDatabasesPath":
return directory.path;
break;
case "query":
return 1;
break;
}
return response;
}
The CachedNetworkImage
widget accepts an optional cacheManager
property (default to a DefaultCacheManager instance).
The idea is to use get_it to inject a DefaultCacheManager
instance in your app, and a custom one in the test. This custom cache manager can return a test asset file.
import 'dart:io';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:flutter_cache_manager/src/cache_store.dart';
import 'package:flutter_cache_manager/src/storage/non_storing_object_provider.dart';
class TestCacheManager extends BaseCacheManager {
TestCacheManager()
: super(
null,
cacheStore: CacheStore(
Future.value(null),
null,
null,
null,
cacheRepoProvider: Future.value(NonStoringObjectProvider()),
),
);
@override
Future<String> getFilePath() async {
return null;
}
@override
Stream<FileResponse> getFileStream(String url,
{Map<String, String> headers, bool withProgress}) async* {
if (url == 'https://myownservice.com/example') {
yield FileInfo(
File('test/assets/mock_image.jpg'),
FileSource.Cache,
DateTime(2050),
url,
);
}
}
}
class MyImage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CachedNetworkImage(
imageUrl: 'https://myownservice.com/example',
cacheManager: GetIt.instance.get<BaseCacheManager>(),
);
}
}
main()
:GetIt.instance.registerSingleton<BaseCacheManager>(
DefaultCacheManager(),
);
main()
:GetIt.instance.registerSingleton<BaseCacheManager>(
TestCacheManager(),
);
Then you should be able to pump an instance of the MyImage
widget:
await tester.pumpWidget(MyImage());
// Important: you need to pump an other frame so the CachedNetworkImage
// can replace the placeholder by the image received from the
// cache manager stream.
await tester.pump();
See this blog post for full explanations, code sample and example app.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.