「这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战」。
Flutter持久化库drift(原moor)官方文档翻译汇总 - 掘金 (juejin.cn)
本文翻译自 drift 的 官方文档 Testing (simonbinder.eu)。
肉翻多有不足,不吝赐教。
测试
为 drift 数据库写单元测试的指南。
使用 drift 的 Flutter 应用一直可以在真机上用 集成测试 来测试。 该指南聚集于为 drift 编写的数据库来编写单元测试。 这些测试可在电脑上运行和调试,不需要附加准备,所以也不需要一个物理设备来运行。
准备
对于该指南,我们准备测试一个存储用户名的简单数据库。和常规的 drift 数据库相比,仅在构造方法中有一处重要的改变:明确 QueryExecutor 的参数,而不是给父类传递固定执行器的无参的构造方法(如FlutterQueryExecutor 或 NativeDatabase)
import 'package:drift/drift.dart';
part 'database.g.dart';
class Users extends Table {
IntColumn get id => integer().autoIncrement()();
TextColumn get name => text()();
}
@DriftDatabase(tables: [Users])
class MyDatabase extends _$MyDatabase {
MyDatabase(QueryExecutor e) : super(e);
@override
int get schemaVersion => 1;
/// 创建一个用户,返回他们的 id.
Future<int> createUser(String name) {
return into(users).insert(UsersCompanion.insert(name: name));
}
/// 用[newName].id]对应的[newName]改变一个相应[id]用户的用户名
Future<void> updateName(int id, String newName) {
return update(users).replace(User(id: id, name: newName));
}
Stream<User> watchUserWithId(int id) {
return (select(users)..where((u) => u.id.equals(id))).watchSingle();
}
}
安装 sqlite 我们不能分发一个 sqlite 安装文件作为一个 pub 包(至少不能作为在 Flutter 构建体系之外的东西),所以需要确保在你的系统中已经有了 sqlite3 的共享库。
在 macOS 上,默认已安装。
在 Linux 上,可以在 Ubuntu 上使用
libsqlite3-dev包,在 Arch 上使用sqlite3包 (其它的发行版也有类似的包)。在 Windows 上, 可以 下载 'Precompiled Binaries for Windows' 后把
sqlite3.dll解压到环境变量PATH指定的目录中。然后重启设备确保应用会在变化后的PATH运行。
编写测试
可以用 NativeDatabase.memory() 代替 FlutterQueryExecutor 或其它实现来创建一个数据库的内存版本。一个打开数据库的合适位置是在 package:test 包的 setUp 和 tearDown 方法:
import 'package:drift/native.dart';
import 'package:test/test.dart';
// 上面定义的文件,当然可以测试任何 drift 数据库。
import 'database.dart';
void main() {
MyDatabase database;
setUp(() {
database = MyDatabase(NativeDatabase.memory());
});
tearDown(() async {
await database.close();
});
}
在适当的位置完成准备后,最终可以如下写一些测试:
test('users can be created', () async {
final id = await database.createUser('some user');
final user = await database.watchUserWithId(id).first;
expect(user.name, 'some user');
});
test('stream emits a new user when the name updates', () async {
final id = await database.createUser('first name');
final expectation = expectLater(
database.watchUserWithId(id).map((user) => user.name),
emitsInOrder(['first name', 'changed name']),
);
await database.updateName(id, 'changed name');
await expectation;
});
测试迁移
drift 会帮助生成用于 schema 迁移的代码。更多详细内容参考该指南。