Flutter模拟Supabase HTTP客户端插件mock_supabase_http_client的使用

Flutter模拟Supabase HTTP客户端插件mock_supabase_http_client的使用

MockSupabaseHttpClient

一个用于测试Supabase API的模拟HTTP客户端。 通过将MockSupabaseHttpClient传递给Supabase客户端,您可以创建一个模拟的Supabase客户端,用于单元测试您的Supabase API调用而不进行实际的网络请求。

它的工作原理是拦截HTTP请求,并返回您插入到模拟数据库中的模拟数据。插入到模拟数据库中的数据将存储在内存中。

import 'package:mock_supabase_http_client/mock_supabase_http_client.dart';
import 'package:supabase/supabase.dart';

final mockSupabase = SupabaseClient(
  'https://mock.supabase.co', // 传入一个有效的URL即可
  'fakeAnonKey', // 传入任意字符串即可
  httpClient: MockSupabaseHttpClient(),
);

特性

  • 向模拟的Supabase客户端添加模拟数据
  • 支持select、insert、update、upsert和delete操作
  • 支持过滤、排序和限制结果
  • 支持引用表操作
  • 可以在测试之间重置模拟数据

安装

在您的开发依赖项中添加mock_supabase_http_client

dev_dependencies:
  mock_supabase_http_client: ^0.0.1

使用

您可以向模拟数据库中插入模拟数据,然后测试您的Supabase API调用。

import 'package:mock_supabase_http_client/mock_supabase_http_client.dart';
import 'package:supabase/supabase.dart';
import 'package:test/test.dart';

void main() {
  late final SupabaseClient mockSupabase;
  late final MockSupabaseHttpClient mockHttpClient;

  setUpAll(() {
    mockHttpClient = MockSupabaseHttpClient();

    // 将模拟客户端传递给Supabase客户端
    mockSupabase = SupabaseClient(
      'https://mock.supabase.co', // 传入一个有效的URL即可
      'fakeAnonKey', // 传入任意字符串即可
      httpClient: MockSupabaseHttpClient(),
    );
  });

  tearDown(() async {
    // 在每个测试之后重置模拟数据
    mockHttpClient.reset();
  });

  tearDownAll(() {
    // 所有测试完成后关闭模拟客户端
    mockHttpClient.close();
  });

  test('插入数据有效', () async {
    // 首先向模拟数据库中插入一些模拟数据
    await mockSupabase.from('posts').insert({'title': 'Hello, world!'});

    // 然后可以测试您的Supabase API调用
    final posts = await mockSupabase.from('posts').select();
    expect(posts.length, 1);
    expect(posts.first, {'title': 'Hello, world!'});
  });

  // 因为模拟的Supabase客户端不知道表结构,
  // 引用表的数据必须以您想要查询的方式插入。
  //
  // 下面的示例展示了`posts`表与`authors`表多对一的关系和与`comments`表一对多的关系。
  test('高级查询,包括过滤和引用表', () async {
    // `posts`表与`authors`表多对一的关系
    // `posts`表与`comments`表一对多的关系
    await mockSupabase.from('posts').insert([
      {
        'id': 1,
        'title': '第一篇帖子',
        'authors': {'id': 1, 'name': '作者一'},
        'comments': [
          {'id': 1, 'content': '第一个评论'},
          {'id': 2, 'content': '第二个评论'}
        ]
      },
      {
        'id': 2,
        'title': '第二篇帖子',
        'authors': {'id': 2, 'name': '作者二'},
        'comments': [
          {'id': 3, 'content': '第三个评论'},
          {'id': 4, 'content': '第四个评论'},
          {'id': 5, 'content': '第五个评论'}
        ]
      }
    ]);

    // 查询`posts`表,包括引用的`authors`数据并进行过滤和排序
    final posts = await mockSupabase
        .from('posts')
        .select('*, authors(*), comments(*)')
        .eq('authors.id', 1)
        .order('id', ascending: false);

    expect(posts.length, 2);
    expect(posts, [
      {
        'id': 2,
        'title': '第二篇帖子',
        'authors': {'id': 2, 'name': '作者二'},
        'comments': [
          {'id': 3, 'content': '第三个评论'},
          {'id': 4, 'content': '第四个评论'},
          {'id': 5, 'content': '第五个评论'},
        ]
      },
      {
        'id': 1,
        'title': '第一篇帖子',
        'authors': {'id': 1, 'name': '作者一'},
        'comments': [
          {'id': 1, 'content': '第一个评论'},
          {'id': 2, 'content': '第二个评论'},
        ]
      },
    ]);
  });
}

当前限制

  • 模拟的Supabase客户端不知道表结构。这意味着它不知道插入的模拟数据是否是引用表数据,或者只是一个数组/JSON对象。这可能会导致返回的数据比您构造的模拟数据更多,特别是当模拟数据中包含多个引用表时。

  • 不支持嵌套的引用表数据。

    // 这样是可以的
    final posts = await mockSupabase.from('posts').select('*, authors(*)');
    // 这样不会返回正确的数据
    final posts = await mockSupabase.from('posts').select('*, authors(*, comments(*))');
    

更多关于Flutter模拟Supabase HTTP客户端插件mock_supabase_http_client的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter模拟Supabase HTTP客户端插件mock_supabase_http_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个使用 mock_supabase_http_client 插件来模拟 Supabase HTTP 客户端请求的 Flutter 代码示例。这个示例展示了如何设置模拟客户端,并使用它来替代实际的 Supabase 客户端进行请求。

首先,确保你已经添加了 mock_supabase_http_client 插件到你的 pubspec.yaml 文件中:

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

然后,你可以按照以下步骤设置和使用模拟客户端:

  1. 创建模拟 Supabase HTTP 客户端
import 'package:mockito/mockito.dart';
import 'package:mock_supabase_http_client/mock_supabase_http_client.dart';
import 'package:supabase/supabase.dart';

class MockSupabaseHttpClient extends Mock implements SupabaseHttpClient {}

void main() {
  // 创建模拟客户端实例
  final mockClient = MockSupabaseHttpClient();

  // 配置模拟客户端的行为
  when(mockClient.post(any, headers: anyNamed('headers'), body: anyNamed('body')))
      .thenAnswer((_) async {
    // 这里可以返回模拟的响应数据
    return Response(
      data: {
        'user': {
          'id': 'mock-user-id',
          'email': 'test@example.com',
        },
      },
      status: 200,
    );
  });

  // 创建 Supabase 客户端实例,并使用模拟的 HTTP 客户端
  final supabaseClient = SupabaseClient(
    url: 'https://your-supabase-url.supabase.co',
    anonKey: 'your-anon-key',
    httpClient: mockClient,  // 使用模拟客户端
  );

  // 使用 Supabase 客户端进行请求
  supabaseClient.auth.signUp(email: 'test@example.com', password: 'password')
      .then((result) {
    // 处理结果,这里 result 应该是模拟的响应数据
    print(result.data);
  }).catchError((error) {
    // 处理错误
    print(error);
  });
}

注意:上面的代码片段中,supabaseClient.auth.signUp 方法的调用只是为了演示如何使用模拟客户端,实际上 signUp 方法不会通过 post 方法进行模拟,你需要根据实际的 API 调用方法调整模拟行为。例如,如果你需要模拟 from 方法调用,你应该调整 whenthenAnswer 的参数。

  1. 在测试中使用模拟客户端

如果你是在测试环境中使用模拟客户端,可以将上述代码放入你的测试文件中(例如 test/supabase_client_test.dart),并使用 Flutter 的测试框架来运行测试:

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:mock_supabase_http_client/mock_supabase_http_client.dart';
import 'package:supabase/supabase.dart';

void main() {
  group('Supabase Client Tests', () {
    late MockSupabaseHttpClient mockClient;
    late SupabaseClient supabaseClient;

    setUp(() {
      mockClient = MockSupabaseHttpClient();
      supabaseClient = SupabaseClient(
        url: 'https://your-supabase-url.supabase.co',
        anonKey: 'your-anon-key',
        httpClient: mockClient,
      );

      // 配置模拟行为
      when(mockClient.post(any, headers: anyNamed('headers'), body: anyNamed('body')))
          .thenAnswer((_) async {
        return Response(
          data: {
            'user': {
              'id': 'mock-user-id',
              'email': 'test@example.com',
            },
          },
          status: 200,
        );
      });
    });

    tearDown(() {
      // 清理模拟客户端
      mockClient.close();
    });

    test('signs up a new user', () async {
      // 这里你应该调用实际的 Supabase 方法,并验证结果
      // 注意:signUp 方法可能不直接通过 post 方法,你需要根据实际情况调整
      final result = await supabaseClient.auth.signUp(email: 'test@example.com', password: 'password');
      expect(result.data!['user']['email'], 'test@example.com');
    });
  });
}

请注意,上述代码片段是为了演示如何设置和使用 mock_supabase_http_client 插件,并非一个完整且可运行的示例。你需要根据自己的实际需求调整代码,特别是模拟行为部分。此外,由于 Supabase SDK 的 API 可能会变化,请参考最新的 Supabase 和 mock_supabase_http_client 文档。

回到顶部