Flutter网络请求模拟插件dio_mocked_responses的使用

Flutter网络请求模拟插件dio_mocked_responses的使用

Forked from Flutter Dio Mock Interceptor

License: MIT Publish to pub.dev

dio_mocked_responses

dio_mocked_responses 是一个用于测试目的的 Flutter 包,它拦截使用 Dio 包进行的 HTTP 请求,并根据预定义的 JSON 文件返回模拟响应。该包有助于在不依赖外部服务的情况下隔离和测试应用程序的功能。

特性

  • 拦截和模拟 HTTP 请求。
  • 配置基于角色和个人情境的响应。
  • 支持基于模板的动态响应。
  • 跟踪请求历史。
  • 与 Dio 包轻松集成。

安装

pubspec.yaml 中添加 dio_mocked_responses

flutter pub add dev:dio_mocked_responses 

使用

基本设置

  1. 导入包:
import 'package:dio_mocked_responses/dio_mocked_responses.dart';
  1. 创建 MockInterceptor 实例:
final dio = Dio();
dio.interceptors.add(MockInterceptor(basePath: 'test/mocks')); // 指定 mock 文件的基本路径
  1. 定义你的模拟响应文件: 模拟响应文件是存储在 basePath 目录下的 JSON 文件。目录结构可以通过角色或情境进行个性化设置。

示例文件结构:

/test/mocks/
  GET_user_profile.json
  POST_login.json
  admin/
    GET_dashboard.json

每个 JSON 文件应定义 HTTP 方法、状态码、响应数据和可选的模板。示例:

{
  "GET": {
    "statusCode": 200,
    "data": {
      "id": 1,
      "name": "John Doe"
    }
  },
  "POST": {
    "statusCode": 201,
    "template": {
      "content": {"message": "Welcome, ${req.data.username}!"}
    }
  }
}

添加角色

角色允许你为特定角色或用户创建模拟响应。设置角色:

MockInterceptor.setPersona('admin');

拦截器将查找对应的 admin/ 子目录中的文件。

清除角色:

MockInterceptor.clearPersona();

添加上下文

上下文为响应添加了另一层定制。例如,你可以定义特定于某种应用程序状态的响应:

MockInterceptor.setContext('logged_in');

拦截器会优先处理具有上下文名称的文件。

清除上下文:

MockInterceptor.clearContext();

查询参数

查询参数会自动解析并可能影响模拟响应。如果端点有查询参数,请确保文件名反映它们,将特殊字符替换为 _

示例:

GET_user_profile?role=admin -> GET_user_profile_role_admin.json

使用模板生成动态响应

模板允许根据请求数据或预定义变量生成动态响应。在你的模拟文件中使用 template 键来定义动态响应。

示例:

{
  "GET": {
    "statusCode": 200,
    "template": {
      "content": {
        "greeting": "Hello, ${req.queryParameters.name}!"
      }
    }
  }
}

这将生成一个响应,其中问候语动态包含来自请求的 name 查询参数。

跟踪请求历史

你可以访问拦截请求的历史记录:

final history = MockInterceptor.history;
history.forEach((item) {
  print('Method: ${item.method}, Path: ${item.path}');
});

清除历史记录:

MockInterceptor.clearHistory();

错误处理

如果找不到文件或路由,拦截器将使用 DioException 拒绝请求:

DioException: Can't find file: test/mocks/GET_user_profile.json

确保你的模拟文件正确结构并且可以从指定的 basePath 访问。

示例测试

这是一个完整的示例,展示了如何在测试中使用 dio_mocked_responses

import 'package:dio/dio.dart';
import 'package:dio_mocked_responses/dio_mocked_responses.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  late Dio dio;

  setUp(() {
    dio = Dio();
    dio.interceptors.add(MockInterceptor(basePath: 'test/mocks'));
  });

  test('GET user profile', () async {
    final response = await dio.get('/user/profile');
    expect(response.statusCode, 200);
    expect(response.data['name'], 'John Doe');
  });
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用dio_mocked_responses插件来模拟网络请求的示例代码。这个插件允许你在不依赖实际网络请求的情况下测试你的网络代码。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加diodio_mocked_responses依赖:

dependencies:
  flutter:
    sdk: flutter
  dio: ^4.0.0 # 请检查最新版本
  dio_mocked_responses: ^0.1.0 # 请检查最新版本

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

2. 导入依赖

在你的Dart文件中导入这两个包:

import 'package:dio/dio.dart';
import 'package:dio_mocked_responses/dio_mocked_responses.dart';

3. 设置模拟响应

接下来,你需要设置你的模拟响应。这通常在测试文件中完成,但你也可以在开发过程中使用它们。

void main() {
  // 创建一个Dio实例
  final dio = Dio();

  // 使用MockAdapter来模拟响应
  final mockAdapter = MockAdapter(dio);

  // 设置一个模拟的GET请求响应
  mockAdapter.onGet(
    Uri.parse('https://api.example.com/data'),
    (RequestOptions options) async {
      return Response(
        data: {
          'message': 'Hello, mocked response!',
          'data': [
            {'id': 1, 'name': 'Item 1'},
            {'id': 2, 'name': 'Item 2'},
          ],
        },
        statusCode: 200,
      );
    },
  );

  // 现在你可以进行网络请求,它将被模拟响应所替代
  dio.get('https://api.example.com/data').then((response) {
    print(response.data);
    // 输出: {message: Hello, mocked response!, data: [{id: 1, name: Item 1}, {id: 2, name: Item 2}]}
  });
}

4. 在测试中使用

如果你在编写单元测试,你可能会希望使用test包来组织你的测试。以下是一个简单的测试示例:

import 'package:dio/dio.dart';
import 'package:dio_mocked_responses/dio_mocked_responses.dart';
import 'package:test/test.dart';

void main() {
  late Dio dio;
  late MockAdapter mockAdapter;

  setUp(() {
    dio = Dio();
    mockAdapter = MockAdapter(dio);
  });

  tearDown(() {
    dio.close();
  });

  test('mocked GET request', () async {
    mockAdapter.onGet(
      Uri.parse('https://api.example.com/data'),
      (RequestOptions options) async {
        return Response(
          data: {
            'message': 'Hello, mocked test!',
            'data': [
              {'id': 1, 'name': 'Test Item 1'},
            ],
          },
          statusCode: 200,
        );
      },
    );

    final response = await dio.get('https://api.example.com/data');

    expect(response.statusCode, 200);
    expect(response.data, {
      'message': 'Hello, mocked test!',
      'data': [
        {'id': 1, 'name': 'Test Item 1'},
      ],
    });
  });
}

注意事项

  • 确保你在测试或开发过程中正确地设置了模拟响应。
  • 清理资源,特别是在测试完成后关闭Dio实例。
  • 检查diodio_mocked_responses的最新版本,因为API可能会随版本变化。

通过上述步骤,你可以在Flutter项目中使用dio_mocked_responses插件来模拟网络请求,从而在不依赖实际网络的情况下进行开发和测试。

回到顶部