简体   繁体   English

使用 NetworkImage 进行 Flutter 小部件测试

[英]Flutter Widget Tests with NetworkImage

I have a Widget with NetworkImage (so far with hard-coded url).我有一个带有NetworkImageWidget (到目前为止,带有硬编码的 url)。
I would like to widget test this Widget, but I got 404 when I run widget test (url is 100% valid).我想对这个小部件进行小部件测试,但是当我运行小部件测试时得到 404(网址 100% 有效)。
How can I make NetworkImages load themselves or (which would be better) ignore them so that my tests won't fail because of 404?我怎样才能让NetworkImages自己加载或(这会更好)忽略它们,这样我的测试就不会因为 404 而失败?

I have a Widget with NetworkImage (so far with hard-coded url).我有一个带有NetworkImageWidget (到目前为止带有硬编码的url)。
I would like to widget test this Widget, but I got 404 when I run widget test (url is 100% valid).我想对小部件进行测试,但是运行小部件测试时得到404(URL为100%有效)。
How can I make NetworkImages load themselves or (which would be better) ignore them so that my tests won't fail because of 404?如何使NetworkImages加载自身(或更好)忽略它们,以使我的测试不会因为404而失败?

I have a Widget with NetworkImage (so far with hard-coded url).我有一个带有NetworkImageWidget (到目前为止带有硬编码的url)。
I would like to widget test this Widget, but I got 404 when I run widget test (url is 100% valid).我想对小部件进行测试,但是运行小部件测试时得到404(URL为100%有效)。
How can I make NetworkImages load themselves or (which would be better) ignore them so that my tests won't fail because of 404?如何使NetworkImages加载自身(或更好)忽略它们,以使我的测试不会因为404而失败?

I have a Widget with NetworkImage (so far with hard-coded url).我有一个带有NetworkImageWidget (到目前为止带有硬编码的url)。
I would like to widget test this Widget, but I got 404 when I run widget test (url is 100% valid).我想对小部件进行测试,但是运行小部件测试时得到404(URL为100%有效)。
How can I make NetworkImages load themselves or (which would be better) ignore them so that my tests won't fail because of 404?如何使NetworkImages加载自身(或更好)忽略它们,以使我的测试不会因为404而失败?

I have a Widget with NetworkImage (so far with hard-coded url).我有一个带有NetworkImageWidget (到目前为止带有硬编码的url)。
I would like to widget test this Widget, but I got 404 when I run widget test (url is 100% valid).我想对小部件进行测试,但是运行小部件测试时得到404(URL为100%有效)。
How can I make NetworkImages load themselves or (which would be better) ignore them so that my tests won't fail because of 404?如何使NetworkImages加载自身(或更好)忽略它们,以使我的测试不会因为404而失败?

I updated the code from Günter Zöchbauer answer using null safety and the mocktail package.我更新从代码冈特Zöchbauer使用空安全和答案无酒精鸡尾酒包。

image_mock_http_client.dart image_mock_http_client.dart

 import 'dart:io'; import 'package:mocktail/mocktail.dart'; class MockHttpOverrides extends HttpOverrides { MockHttpOverrides(this.data); final Map<Uri, List<int>> data; @override HttpClient createHttpClient(SecurityContext? context) { final client = MockHttpClient(); final request = MockHttpClientRequest(); final response = MockHttpClientResponse(data); final headers = MockHttpHeaders(); /// Comment the exception when stub is missing from client /// because it complains about missing autoUncompress stub /// even setting it up as shown bellow. // throwOnMissingStub(client); throwOnMissingStub(request); throwOnMissingStub(response); throwOnMissingStub(headers); // This line is not necessary, it can be omitted. when(() => client.autoUncompress).thenReturn(true); // Use decompressed, otherwise you will get bad data. when(() => response.compressionState) .thenReturn(HttpClientResponseCompressionState.decompressed); // Capture the url and assigns it to requestedUrl from MockHttpClientResponse. when(() => client.getUrl(captureAny())).thenAnswer((invocation) { response.requestedUrl = invocation.positionalArguments[0] as Uri; return Future<HttpClientRequest>.value(request); }); // This line is not necessary, it can be omitted. when(() => request.headers).thenAnswer((_) => headers); when(() => request.close()) .thenAnswer((_) => Future<HttpClientResponse>.value(response)); when(() => response.contentLength) .thenAnswer((_) => data[response.requestedUrl]!.length); when(() => response.statusCode).thenReturn(HttpStatus.ok); when( () => response.listen( captureAny(), cancelOnError: captureAny(named: 'cancelOnError'), onDone: captureAny(named: 'onDone'), onError: captureAny(named: 'onError'), ), ).thenAnswer((invocation) { final onData = invocation.positionalArguments[0] as void Function(List<int>); final onDone = invocation.namedArguments[#onDone] as void Function(); final onError = invocation.namedArguments[#onError] as void Function(Object, [StackTrace]); final cancelOnError = invocation.namedArguments[#cancelOnError] as bool; return Stream<List<int>>.fromIterable([data[response.requestedUrl]!]) .listen( onData, onDone: onDone, onError: onError, cancelOnError: cancelOnError, ); }); return client; } } class MockHttpClient extends Mock implements HttpClient {} class MockHttpClientRequest extends Mock implements HttpClientRequest {} class MockHttpClientResponse extends Mock implements HttpClientResponse { MockHttpClientResponse(this.data); final Map<Uri, List<int>> data; Uri? requestedUrl; // It is not necessary to override this method to pass the test. @override Future<S> fold<S>( S initialValue, S Function(S previous, List<int> element) combine, ) { return Stream.fromIterable([data[requestedUrl]]) .fold(initialValue, combine as S Function(S, List<int>?)); } } class MockHttpHeaders extends Mock implements HttpHeaders {}

my_test.dart my_test.dart

 const _imageUrl = 'https://your.image.uri.here'; void main() { setUp(() async { registerFallbackValue(Uri()); // Load an image from assets and transform it from bytes to List<int> final _imageByteData = await rootBundle.load('assets/images/image.png'); final _imageIntList = _imageByteData.buffer.asInt8List(); final _requestsMap = { Uri.parse(_imageUrl): _imageIntList, }; HttpOverrides.global = MockHttpOverrides(_requestsMap); }); ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM