我有一个Widget与NetworkImage(所以用硬编码的网址远)。
我想对小部件进行测试,但运行小部件测试时得到404(URL为100%有效)。
我如何自己进行NetworkImages加载或(最好是)忽略它们,以使我的测试不会因为404而失败?
Ton*_*ado 18
几年后,现在image_test_utils包似乎不再维护,这是此问题的另一个简单解决方案。
我使用了network_image_mock包(支持nullsafety)并在测试中仅添加了两行代码。像这样包装你的pumpWidget呼叫mockNetworkImagesFor,你将不会再收到图像加载错误:
mockNetworkImagesFor(() => tester.pumpWidget(makeTestableWidget()));
Run Code Online (Sandbox Code Playgroud)
Iir*_*kka 13
在小部件测试中,默认的HTTP客户端已替换为始终返回400s的HTTP客户端。在flutter_markdown存储库中以及其他几个地方,都有一个有关如何执行此操作的示例。我曾经将其复制并粘贴到每个项目中,但是我做了足够多次以至于变得很无聊。
(我自己)现在有一个名为“ image_test_utils”的库。您可以使用一种provideMockedNetworkImages方法包装小部件测试,该方法将模拟的HTTP客户端替换为始终返回透明图像的HTTP客户端。这又使您的测试通过。
pubspec.yaml:
dev_dependencies:
image_test_utils: ^1.0.0
Run Code Online (Sandbox Code Playgroud)
my_image_test.dart:
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:image_test_utils/image_test_utils.dart';
void main() {
testWidgets('my image test', (WidgetTester tester) async {
provideMockedNetworkImages(() async {
/// Now we can pump NetworkImages without crashing our tests. Yay!
await tester.pumpWidget(
MaterialApp(
home: Image.network('https://example.com/image.png'),
),
);
/// No crashes.
});
});
}
Run Code Online (Sandbox Code Playgroud)
如果您遇到这种非常不寻常的情况,即小部件测试完全是关于图像是否被正确获取,您可以撤消覆盖。
对于每个测试:
setUpAll(() => HttpOverrides.global = null);
Run Code Online (Sandbox Code Playgroud)
对于单个测试:
testWidgets('Image gets correctly fetched.', () {
HttpOverrides.runZoned(
// Run your tests.
() {},
createHttpClient: (securityContext) => MockHttpClient(securityContext),
);
});
Run Code Online (Sandbox Code Playgroud)
我用
import 'package:flutter/services.dart' show createHttpClient;
final imageUri = Uri.parse('http://example.com$dummyImagePath');
testWidgets( ...) {
createHttpClient = createMockImageHttpClient;
await tester.pumpWidget(new TestWrapperWidget(
child: (_) => new ImageWidget(name: text, url: imageUri)));
}
Run Code Online (Sandbox Code Playgroud)
import 'dart:async' show Future;
import 'package:http/http.dart' show Client, Response;
import 'package:http/testing.dart' show MockClient;
import 'dummy_image_data.dart'
show dummyImageData;
const String dummyImagePath = '/image.jpg';
Client createMockImageHttpClient() => new MockClient((request) {
switch (request.url.path) {
case dummyImagePath:
return new Future<Response>.value(new Response.bytes(
dummyImageData, 200,
request: request, headers: {'Content-type': 'image/jpg'}));
default:
return new Future<Response>.value(new Response('', 404));
}
});
Run Code Online (Sandbox Code Playgroud)
Uint8List get dummyImageData => BASE64.decode(dummyJpgImageBase64);
Run Code Online (Sandbox Code Playgroud)
(我使用http://base64.wutils.com/encoding-online/创建了图像数据Base64 )
const String dummyAvatarJpgImageBase64 =
'/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBwgHBgkIBwgKCgkLDRYPDQwMDRsUFRAWIB0iIi'
...
'itf93F+MLRdehP4ZutvWj8m+rjzpz//Z';
Run Code Online (Sandbox Code Playgroud)
这样,当我从开始测试时,它也可以工作flutter run -t test/image_test.dart,但是图像数据也可以从图像文件中提供,以进行正常的测试运行。
使用mockito包装
image_mock_http_client.dart
import 'dart:async' show Future, Stream;
import 'dart:io'
show
HttpClient,
HttpClientRequest,
HttpClientResponse,
HttpHeaders,
HttpOverrides,
HttpStatus,
SecurityContext;
import '.dummy_image_data.dart';
import 'package:mockito/mockito.dart'
show Mock, any, anyNamed, captureAny, throwOnMissingStub, when;
const String dummyAvatarImagePath = '/avatar.jpg';
class TestHttpOverrides extends HttpOverrides {
TestHttpOverrides(this.data);
final Map<Uri, List<int>> data;
@override
HttpClient createHttpClient(SecurityContext context) =>
createMockImageHttpClient(context, data);
}
// Returns a mock HTTP client that responds with an image to all requests.
MockHttpClient createMockImageHttpClient(
SecurityContext _, Map<Uri, List<int>> data) {
final client = new MockHttpClient();
final request = new MockHttpClientRequest();
final response = new MockHttpClientResponse(data);
final headers = new MockHttpHeaders();
throwOnMissingStub(client);
throwOnMissingStub(request);
throwOnMissingStub(response);
throwOnMissingStub(headers);
when<dynamic>(client.getUrl(captureAny)).thenAnswer((invocation) {
response.requestedUrl = invocation.positionalArguments[0] as Uri;
return new Future<HttpClientRequest>.value(request);
});
when(request.headers).thenAnswer((_) => headers);
when(request.close())
.thenAnswer((_) => new Future<HttpClientResponse>.value(response));
when(response.contentLength)
.thenAnswer((_) => data[response.requestedUrl].length);
when(response.statusCode).thenReturn(HttpStatus.ok);
when(
response.listen(
any,
cancelOnError: anyNamed('cancelOnError'),
onDone: anyNamed('onDone'),
onError: anyNamed('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 new 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;
@override
Future<S> fold<S>(S initialValue, S combine(S previous, List<int> element)) =>
new Stream.fromIterable([data[requestedUrl]]).fold(initialValue, combine);
}
class MockHttpHeaders extends Mock implements HttpHeaders {}
Run Code Online (Sandbox Code Playgroud)
my_test.dart
import 'image_mock_http_client.dart' show TestHttpOverrides;
...
setUp(() async {
HttpOverrides.global = new TestHttpOverrides({
'http://example.com/my_image.png': dummyAvatarImageData,
'http://example.com/other_image.png: dummyPngImageData,
});
});
Run Code Online (Sandbox Code Playgroud)
dummyAvatarImageData和dummyPngImageData是list<int>并且包含图像数据。
| 归档时间: |
|
| 查看次数: |
2178 次 |
| 最近记录: |