Flutter中Mock SQFlite数据库的简便测试方案(替代Mockito)
Flutter中Mock SQFlite数据库的最简方案
方案一:使用内存版SQFlite(推荐)
直接用sqflite_common_ffi提供的内存数据库,它是真实的SQFlite引擎,数据仅存在内存中,测试结束自动销毁。无需Mock任何方法,直接跑真实的数据库操作流程,最适合验证toMap->insert->query->fromMap的完整链路。
步骤:
- 添加依赖到
dev_dependencies:
dev_dependencies: sqflite_common_ffi: ^2.3.0 test: any
- 测试代码示例:
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
相关产品推荐
相关产品推荐

