Dart集成测试中DatabaseManagerMock的存放位置与注入方案问询
解决方案:手动覆盖依赖+测试目录实现测试数据库管理器
步骤1:在test目录下创建测试专用的DatabaseManager实现
不用Mock,而是编写基于sqflite_ffi的内存数据库实现,放在test/utils/test_database_manager.dart:
import 'package:sqflite/sqflite.dart'; import 'package:sqflite_ffi/sqflite_ffi.dart'; import '../lib/path/to/database_manager.dart'; // 导入抽象类 class TestDatabaseManager implements DatabaseManager { late Database _db; @override Future<void> init() async { // 初始化sqflite_ffi sqfliteFfiInit(); _db = await databaseFactoryFfi.openDatabase( inMemoryDatabasePath, options: OpenDatabaseOptions( onCreate: (db, version) { // 执行和生产环境一致的建表语句 return db.execute('CREATE TABLE ...'); }, version: 1, ), ); // 填充测试初始化数据 await _insertTestData(); } // 实现DatabaseManager的所有抽象方法,直接操作内存数据库 @override Future<List<SomeModel>> getSomeData() async { final List<Map<String, dynamic>> maps = await _db.query('some_table'); return List.generate(maps.length, (i) => SomeModel.fromMap(maps[i])); } Future<void> _insertTestData() async { // 插入测试用数据 await _db.insert('some_table', {'name': 'test data'}); } @override Future<void> close() async => _db.close(); }
步骤2:在测试中手动覆盖依赖
无需生成第二个injectable配置,测试初始化时先加载主项目依赖,再覆盖DatabaseManager的实现:
import 'package:get_it/get_it.dart'; import 'package:injectable/injectable.dart'; import 'package:test/test.dart'; import '../lib/injection.dart'; // 导入主项目的injectable配置 import 'utils/test_database_manager.dart'; void main() { late GetIt getIt; setUp(() async { // 初始化主项目依赖 getIt = GetIt.instance; await configureDependencies(Environment.prod); // 替换为你使用的环境标识 // 覆盖已注册的DatabaseManager为测试实现 getIt.registerLazySingleton<DatabaseManager>( () => TestDatabaseManager(), override: true, // 允许覆盖已注册类型 ); // 初始化测试数据库 await getIt<DatabaseManager>().init(); }); tearDown(() async { // 测试结束后关闭数据库并重置GetIt await getIt<DatabaseManager>().close(); await getIt.reset(); }); test('测试依赖DatabaseManager的业务流程', () async { final someClass = getIt<SomeClass>(); final result = await someClass.doSomething(); expect(result, equals('预期结果')); }); }
处理depend_on_referenced_packages警告
由于sqflite_ffi是dev依赖,测试目录代码导入它会触发警告,可在项目根目录的analysis_options.yaml中添加规则忽略:
linter: rules: - depend_on_referenced_packages: exclude: - test/**/*.dart
方案优势
- 测试代码完全隔离在test目录,不污染生产代码
- 跳过injectable多配置生成的路径问题,实现更简洁
- 测试用DatabaseManager是真实实现,更适配集成测试对数据库交互逻辑的验证需求
内容的提问来源于stack exchange,提问作者splaytreez
相关产品推荐
相关产品推荐

