FlutterでDriftを使用してみた～テスト編～

# はじめに
FlutterにDriftを導入したときの手順を残しておきます。
今回はテストを書いたときについてです。

本記事は以下の公式ドキュメントを参考にしています。
詳しいことが知りたい方はこちらを参照してください。

https://drift.simonbinder.eu/docs/testing/



# 環境
![Dart-2.19.6](https://img.shields.io/badge/Dart-2.19.6-blue)![Flutter-3.7.12](https://img.shields.io/badge/Flutter-3.7.12-blue)![Drift-2.7.0](https://img.shields.io/badge/Drift-2.7.0-blue)

# テスト用の設定
テストでメモリ上にデータベースを展開できるようにするために、コンストラクタで設定を受け取れるように修正しておきます。

``` diff_dart: database.dart
@DriftDatabase(tables: [Todos, Categories])
class MyDatabase extends _$MyDatabase {
  // コンストラクタでDBの保存先を定義する
-  MyDatabase() : super(_openConnection());
+  MyDatabase(QueryExecutor e) : super(e);
  // マイグレーションを行う場合に使用ため、テーブルを追加／変更／削除する場合はこの値をインクリメントする
  @override
  int get schemaVersion => 1;
}
```

上記のように修正することで、下記のように使用するデータベースの設定が変更できるようになります。
とはいえ、毎回コンストラクタに設定方法を渡すのは煩わしいので [おまけに書いたやり方](#おまけ) のほうが好みです。
``` Dart: exsample
// SQLiteファイルを使う
fileDb = MyDatabase(_openConnection());

// メモリを使う
memoryDb = MyDatabase(NativeDatabase.memory());
```
# テストコード
``` diff_dart: database_test.dart
import 'package:drift/native.dart';
import 'package:test/test.dart';

import 'package:src/database/database.dart'; // 自分のデータベースクラスをインポート

void main() {
  MyDatabase database;

  setUp(() {
    // データベースをメモリ上に展開
    database = MyDatabase(NativeDatabase.memory());
  });

  tearDown(() async {
    // テストが終了したらデータベースを削除
    await database.close();
  });
  
  test('some kind of test.', () async {
    // ここにテストコードを書く
  });

}
```

# おまけ
ここではMyDatabaseを変更前と同じ使い方をしつつ、テストでも使用できるようにする方法を紹介します。
このやり方が正しいのかわからないので、間違っていたら指摘いただけると嬉しいです。
``` diff_dart: database.dart
@DriftDatabase(tables: [Todos, Categories])
class MyDatabase extends _$MyDatabase {
-  // コンストラクタでDBの保存先を定義する
-  MyDatabase(QueryExecutor e) : super(e);
+ // コンストラクタを隠蔽
+  MyDatabase._(QueryExecutor e) : super(e);

+  // SQLite用のファクトリー
+  // factory constractorを利用してコンストラクタを再定義
+  factory MyDatabase() {
+    return MyDatabase._(_openConnection());
+  }
+
+  // テスト用のファクトリー
+  // factory constractorをテスト用のメモリを使用するコンストラクタを定義
+  factory MyDatabase.memory() {
+    return MyDatabase._(NativeDatabase.memory());
+  }
+  // テスト用のファクトリー
+  // factory constractorをテスト用のメモリを使用するコンストラクタを定義
+  factory MyDatabase.fotTest(QueryExecutor e) {
+    return MyDatabase._(e);
+  }


  @override
  int get schemaVersion => 1;
}

```

``` diff_Dart: exsample
// SQLiteファイルを使う
- fileDb = MyDatabase(_openConnection());
+ fileDb = MyDatabase(); 

// メモリを使う
- memoryDb = MyDatabase(NativeDatabase.memory());
+ memoryDb = MyDatabase.memory();
```

<details><summary>コピペしたい人用</summary>

公式ドキュメントをそのまま翻訳しただけのものですが、載せておきます。

``` diff_dart: database.dart
@DriftDatabase(tables: [Todos, Categories])
class MyDatabase extends _$MyDatabase {
  // コンストラクタを隠蔽
  MyDatabase._(QueryExecutor e) : super(e);

  // SQLite用のファクトリー
  // factory constractorを利用してコンストラクタを再定義
  factory MyDatabase() {
    return MyDatabase._(_openConnection());
  }

  // テスト用のファクトリー
  // factory constractorをテスト用のメモリを使用するコンストラクタを定義
  factory MyDatabase.memory() {
    return MyDatabase._(NativeDatabase.memory());
  }
  // テスト用のファクトリー
  // factory constractorをテスト用のメモリを使用するコンストラクタを定義
  factory MyDatabase.fotTest(QueryExecutor e) {
    return MyDatabase._(e);
  }

  @override
  int get schemaVersion => 1;
}
```

``` diff_dart: database_test.dart
import 'package:drift/native.dart';
import 'package:test/test.dart';

import 'package:src/database/database.dart'; // 自分のデータベースクラスをインポート

void main() {
  MyDatabase database;

  setUp(() {
    // データベースをメモリ上に展開
    database = MyDatabase.memory();
  });

  tearDown(() async {
    // テストが終了したらデータベースを削除
    await database.close();
  });
  
  test('some kind of test.', () async {
    // ここにテストコードを書く
  });

}
```
</details>

# Driftを使ってみたメモ
今までDriftを使ってきてのメモです。
## 初期構築編
https://qiita.com/team7_403_poppin/items/b6eb8a15ef716834f2e5