为 SQLite 数据库 API 编写 flutter 单元测试时出错

问题描述 投票:0回答:1

我正在尝试为我的 flutter 数据库 API 编写一个测试文件。我有一个预填充的数据库,我想在该数据库上执行测试,该数据库存储在 asset/database/ 中,名为database.db。

pubspec.yaml:

dev_dependencies:
  flutter_lints: ^4.0.0
  flutter_launcher_icons: ^0.13.1
  flutter_test:
    sdk: flutter
  sqflite_common_ffi: ^2.3.3

flutter:
  uses-material-design: true
  generate: true
  assets:
    - assets/images/
    - assets/database/

database_api.dart:

import 'dart:io';
import 'package:flutter/services.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';

class DatabaseAPI {
  static final DatabaseAPI _instance = DatabaseAPI._internal();
  static Database? _db;
  final String _dbName = "database.db";

  DatabaseAPI._internal();

  factory DatabaseAPI() {
    return _instance;
  }

  Future<Database?> get db async {
    if (_db != null) {
      return _db;
    } else {
      _db = await _initDB();
      return _db;
    }
  }

  Future<Database> _initDB() async {
    final path = join(await getDatabasesPath(), _dbName);
    final exist = await databaseExists(path);
    if(!exist) {
      try {
        ByteData data = await rootBundle.load(join('assets', 'database', _dbName));
        List<int> bytes = data.buffer.asUint8List();
        await File(path).writeAsBytes(bytes);
      } catch (error) {
        throw Exception('Error copying database: $error');
      }
    }
    return await openDatabase(path);
  }

  Future<String> fetchLanguage() async {
    var dbClient = await db;
    final List<Map<String, Object?>> list = await dbClient!.query('language');
    var lang = list[0]['selected'];
    return lang.toString();
  }
}

这就是我编写测试文件的方式

database_api_test.dart:

import 'package:flutter_test/flutter_test.dart';
import 'package:drinking_game/db_api/database_api.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  databaseFactory = databaseFactoryFfi;

  test('fetchLanguage returns correct data', () async {
    var api = DatabaseAPI();
    var lang = await api.fetchLanguage();
    print(lang);
    expect(lang, "Italiano");
  });
}

生成的错误是:

Exception: Error copying database: Unable to load asset: "assets\database\database.db".
  The asset does not exist or has empty data.
  package:drinking_game/db_api/new_database_api.dart 49:9  DatabaseAPI._initDB

但是这个错误是在我运行测试时出现的,当我进行正常构建时,我没有错误。我该如何解决这个问题?

flutter sqlite unit-testing
1个回答
0
投票

测试环境不是正常的应用程序环境,这就是您在测试时看到此问题的原因。 您需要执行以下一项或两项操作:

  1. 使用
    testWidgets('myTest', (tester)
    而不是
    test('myTest', ()
  2. 将测试定义为 Widgets 测试
  3. 在您的
    setUp
    方法中,将您想要在测试中访问的文件从资产目录复制到可访问的目录,例如
    // copy the test database files from assets to documents directory
    Directory directory = await getApplicationDocumentsDirectory();
    for (final filename in [db1, db2, db3]) {
      var uploadFilePath = join(directory.path, filename);
      ByteData data = await rootBundle.load("assets/$filename");
      final buffer = data.buffer;
      File(uploadFilePath).writeAsBytesSync(
          buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
    }
© www.soinside.com 2019 - 2024. All rights reserved.