Flutter网络模拟与Mock数据插件http_miracle_mock的使用

Flutter网络模拟与Mock数据插件http_miracle_mock的使用

标题

Flutter网络模拟与Mock数据插件http_miracle_mock的使用

内容

http_miracle_mock

  • 设计用于Flutter单元测试,此库允许轻松模拟/拦截业务逻辑中的网络请求和图片。

现有框架

  • mockito: 不够简洁,需要大量代码。
  • http_mock_adapter: 只支持Dio库。
  • network_image_mock: 只支持图片。

目标解决的问题

  1. 使用简单。
  2. 兼容主流网络框架,如dio和http。
  3. 处理网络相关问题,如常见网络请求和图片资源。

Getting Started

添加依赖
dev_dependencies:
  http_miracle_mock: any
简单使用
  • 模拟GET请求
void main() async {
  TestWidgetsFlutterBinding.ensureInitialized();
  final HttpMiracleMock httpMiracleMock = HttpMiracleMock();
  final httpClient = HttpClient();
  test('test getUrl', () async {
    var url = 'https://example.com/create';
    var data = "resultGetUrl";
    var uri = Uri.parse(url);
    httpMiracleMock.open(url).reply(data);
    final request = await httpClient.getUrl(uri);
    final response = await request.close();
    var responseData = await response.transform(utf8.decoder).join();
    expect(responseData, data);
  });
}
  • 模拟图片
testWidgets('test image using url png', (WidgetTester tester) async {
  var data = File(path.join(Utils.currentPath, 'test', 'assets', 'test.png'));
  var url = 'http://example.com/image.png';
  httpMiracleMock.open(url).reply(data.readAsBytesSync());
  await Utils.pumpWidgetWithImages(
    tester,
    Column(
      children: [
        Container(
            child: Image.network(
          url,
          width: 100,
          height: 100,
        )),
      ],
    ),
  );
  await tester.pumpAndSettle();
  await expectLater(
    find.byType(Column),
    matchesGoldenFile('snapshots/net_work_image_1.png'),
  );
});
  • 初始化HttpMiracleMock,然后使用httpMiracleMock.open提供需要拦截网络请求的信息,如请求URL和参数,并 使用reply进入请求结果。

API

  • 库仅提供HttpMiracleMock对象,提供open接口。

open

  • open方法主要用于定义要拦截的请求信息,参数如下:

    • url: 必需,要拦截的请求URL,可以传递为String、RegExp或Uri。
    • method: 可选,要拦截的请求方法(GET/POST)。
    • data: 可选,请求参数。
    • dataTransform: 可选,用于请求参数转换,如果某些请求由于兼容性问题无法解析参数,此回调可以用于自定义转换。
  • 返回ResponseData

reply

  • body: 必需,返回的数据内容。
  • statusCode: 可选,返回的状态码。
  • headers: 返回的头部信息。

示例代码

import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:http_miracle_mock/http_miracle_mock.dart';
import 'package:path/path.dart' as path;

void main() async {
  TestWidgetsFlutterBinding.ensureInitialized();
  final HttpMiracleMock httpMiracleMock = HttpMiracleMock();
  final httpClient = HttpClient();

  test('test getUrl', () async {
    var url = 'https://example.com/create';
    var data = "resultGetUrl";
    var uri = Uri.parse(url);
    httpMiracleMock.open(url).reply(data);
    final request = await httpClient.getUrl(uri);
    final response = await request.close();
    var responseData = await response.transform(utf8.decoder).join();
    expect(responseData, data);
  });

  testWidgets('test image using url png', (WidgetTester tester) async {
    var data = File(path.join(currentPath, 'test', 'assets', 'test.png'));
    var url = 'http://example.com/image.png';
    httpMiracleMock.open(url).reply(data.readAsBytesSync());
    await pumpWidgetWithImages(
      tester,
      Column(
        children: [
          Container(
              child: Image.network(
            url,
            width: 100,
            height: 100,
          )),
        ],
      ),
    );
    await tester.pumpAndSettle();
    await expectLater(
      find.byType(Column),
      matchesGoldenFile('snapshots/net_work_image_1.png'),
    );
  });
}

String currentPath = path.join(Platform.environment['PWD']!);

Future<void> pumpWidgetWithImages(
  WidgetTester tester,
  Widget widget,
  List<ImageProvider> providers,
) async {
  Future<void>? precacheFuture;
  await tester.pumpWidget(
    Builder(builder: (buildContext) {
      precacheFuture = tester.runAsync(() async {
        await Future.wait([
          for (final provider in providers)
            precacheImage(
              provider,
              buildContext,
            ),
        ]);
      });
      return widget;
    }),
  );
  await precacheFuture;
}

更多关于Flutter网络模拟与Mock数据插件http_miracle_mock的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网络模拟与Mock数据插件http_miracle_mock的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用http_miracle_mock插件来进行网络模拟和Mock数据的示例代码。这个插件允许你在开发过程中模拟HTTP请求,而不必依赖实际的后端服务。

1. 安装http_miracle_mock插件

首先,你需要在你的Flutter项目中添加http_miracle_mock依赖。打开你的pubspec.yaml文件,并在dependencies部分添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  http_miracle_mock: ^最新版本号  # 替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

2. 配置Mock数据

接下来,你需要在你的项目中创建一个Mock数据文件。例如,你可以创建一个名为mock_data.dart的文件,并在其中定义你的Mock数据。

// mock_data.dart
import 'package:http_miracle_mock/http_miracle_mock.dart';

List<MockRule> mockRules = [
  MockRule(
    path: '/api/users',
    method: HttpMethod.get,
    response: MockResponse(
      statusCode: 200,
      body: '''
      [
        {"id": 1, "name": "John Doe"},
        {"id": 2, "name": "Jane Smith"}
      ]
      ''',
      headers: {
        'Content-Type': 'application/json',
      },
    ),
  ),
  MockRule(
    path: '/api/users/\\d+',
    method: HttpMethod.get,
    response: MockResponse(
      statusCode: 200,
      body: '''
      {
        "id": $1,
        "name": "Mocked User $1"
      }
      ''',
      headers: {
        'Content-Type': 'application/json',
      },
      useRegexForPath: true,
    ),
  ),
];

在这个例子中,我们定义了两个Mock规则:

  1. 第一个规则匹配/api/users的GET请求,并返回一个包含两个用户的JSON数组。
  2. 第二个规则匹配/api/users/数字的GET请求,其中数字可以是任何数字,并返回一个包含该数字的用户信息的JSON对象。

3. 使用Mock插件

在你的main.dart文件或任何其他文件中,你需要初始化Mock插件并使用它。

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:http_miracle_mock/http_miracle_mock.dart';
import 'mock_data.dart';

void main() {
  // 初始化Mock插件
  HttpMiracleMock.init(mockRules);

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Mock Data Example'),
        ),
        body: Center(
          child: FutureBuilder<List<dynamic>>(
            future: fetchUsers(),
            builder: (context, snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return CircularProgressIndicator();
              } else if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              } else {
                return ListView.builder(
                  itemCount: snapshot.data?.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text('${snapshot.data![index]['name']}'),
                    );
                  },
                );
              }
            },
          ),
        ),
      ),
    );
  }

  Future<List<dynamic>> fetchUsers() async {
    final response = await http.get(Uri.parse('https://yourappdomain.com/api/users'));

    if (response.statusCode == 200) {
      return http.jsonDecode(response.body) as List<dynamic>;
    } else {
      throw Exception('Failed to load users');
    }
  }
}

在这个例子中,我们创建了一个简单的Flutter应用,它从/api/users路径获取用户数据并显示在列表中。由于我们已经在main函数中初始化了Mock插件,并提供了Mock规则,因此这个HTTP请求将返回Mock数据,而不是从实际的后端服务获取数据。

注意事项

  • 确保你的Flutter环境和依赖项是最新的。
  • 在实际部署时,记得移除或禁用Mock插件,以便应用能够连接到实际的后端服务。

这样,你就可以在Flutter项目中使用http_miracle_mock插件来模拟网络请求和Mock数据了。

回到顶部