You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Mock SQFlite数据库的简便测试方案(替代Mockito)

Flutter中Mock SQFlite数据库的最简方案

方案一:使用内存版SQFlite(推荐)

直接用sqflite_common_ffi提供的内存数据库,它是真实的SQFlite引擎,数据仅存在内存中,测试结束自动销毁。无需Mock任何方法,直接跑真实的数据库操作流程,最适合验证toMap->insert->query->fromMap的完整链路。

步骤:

  1. 添加依赖到dev_dependencies:
dev_dependencies:
  sqflite_common_ffi: ^2.3.0
  test: any
  1. 测试代码示例:
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
import 'package:test/test.dart';

// 示例数据模型
class User {
  final int id;
  final String name;

  User({required this.id, required this.name});

  Map<String, dynamic> toMap() {
    return {'id': id, 'name': name};
  }

  static User fromMap(Map<String, dynamic> map) {
    return User(id: map['id'], name: map['name']);
  }
}

// 示例数据库操作类
class UserDao {
  final Database db;

  UserDao(this.db);

  Future<void> insertUser(User user) async {
    await db.insert('users', user.toMap());
  }

  Future<User?> getUser(int id) async {
    final maps = await db.query('users', where: 'id = ?', whereArgs: [id]);
    return maps.isNotEmpty ? User.fromMap(maps.first) : null;
  }
}

void main() {
  setUpAll(() {
    // 初始化FFI内存数据库
    sqfliteFfiInit();
    databaseFactory = databaseFactoryFfi;
  });

  test('验证toMap->insert->query->fromMap流程', () async {
    // 创建内存数据库并建表
    final db = await openDatabase(inMemoryDatabasePath, version: 1,
        onCreate: (db, version) async {
      await db.execute('''
        CREATE TABLE users (
          id INTEGER PRIMARY KEY,
          name TEXT
        )
      ''');
    });

    final userDao = UserDao(db);
    final testUser = User(id: 1, name: 'Test User');

    // 执行插入与查询
    await userDao.insertUser(testUser);
    final fetchedUser = await userDao.getUser(1);

    // 验证结果
    expect(fetchedUser, isNotNull);
    expect(fetchedUser?.id, testUser.id);
    expect(fetchedUser?.name, testUser.name);

    await db.close();
  });
}

这种方式完全复用真实数据库逻辑,测试结果更贴近生产场景,避免了Mockito大量桩代码的繁琐。

方案二:手写极简Mock类(轻量场景)

如果不想引入额外依赖,可手写一个极简Mock类,用内存Map模拟表数据,只实现你需要的insert和query方法:

代码示例:

import 'package:test/test.dart';

// 示例数据模型
class User {
  final int id;
  final String name;

  User({required this.id, required this.name});

  Map<String, dynamic> toMap() {
    return {'id': id, 'name': name};
  }

  static User fromMap(Map<String, dynamic> map) {
    return User(id: map['id'], name: map['name']);
  }
}

// 极简Mock数据库
class MockDatabase {
  final Map<String, List<Map<String, dynamic>>> _tables = {'users': []};

  Future<void> insert(String table, Map<String, dynamic> values) async {
    _tables[table]?.add(values);
  }

  Future<List<Map<String, dynamic>>> query(String table, {String? where, List<Object>? whereArgs}) async {
    // 仅适配id匹配的简单场景,按需扩展
    if (where == 'id = ?' && whereArgs != null) {
      final targetId = whereArgs.first as int;
      return _tables[table]?.where((row) => row['id'] == targetId).toList() ?? [];
    }
    return _tables[table] ?? [];
  }
}

// 示例数据库操作类
class UserDao {
  final dynamic db;

  UserDao(this.db);

  Future<void> insertUser(User user) async {
    await db.insert('users', user.toMap());
  }

  Future<User?> getUser(int id) async {
    final maps = await db.query('users', where: 'id = ?', whereArgs: [id]);
    return maps.isNotEmpty ? User.fromMap(maps.first) : null;
  }
}

void main() {
  test('验证toMap->insert->query->fromMap流程', () async {
    final mockDb = MockDatabase();
    final userDao = UserDao(mockDb);
    final testUser = User(id: 1, name: 'Test User');

    await userDao.insertUser(testUser);
    final fetchedUser = await userDao.getUser(1);

    expect(fetchedUser, isNotNull);
    expect(fetchedUser?.id, testUser.id);
    expect(fetchedUser?.name, testUser.name);
  });
}

这种方式零额外依赖,代码量极少,完全针对目标流程定制,无需处理复杂Mock逻辑。


内容的提问来源于stack exchange,提问作者Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 14:15:05