はじめに
今まで私が携わったプロジェクトは中小型の案件が多かったため
ビジネス層からLinqでガシガシDBContextをいじり、テストはローカルDBにテスト用データを投入して行うテストが多かったです。
しかし、昨今のテストファーストやクリーンアーキテクチャの流れ、またMicrosoftも次の指針をだしており一度簡単にまとめてみたいと思います。
Microsoftの指針
推奨のテストアプローチ
まず最初の選択肢は、実際のデータベース(ローカル環境)を使用するかテストダブルを使用するかだそうです。
実際のデータベースを使ったテストの経験はあるのですが以下の問題があります。
- テストレスポンス(テストが多くなるとそれなりの時間がかかる)
- テストの相互干渉(初期化とかIDをランダムに生成したりデータセットアップが面倒な記憶があります)
以降では、上記の問題を解消できるであろうテストダブルについて見ていきたいと思います。
テストダブル
テストダブルでは以下が推奨されています。(以下の図が例示されています)
- SQLite(インメモリ)をデータベースフェイクとして使用
- リポジトリ層を設けモック化する
SQLiteについては、必ずしも実際のデータベースをフェイクできるわけではないので注意が必要とのこと(SQLの非互換)
リポジトリ層については以下のようにコストを度外視すればベストとのこと(結構大変。。)
EF Core を完全にテストから除外し、リポジトリを完全にモックすることができます。ただし、これによってアプリケーションのアーキテクチャが大きく変化する可能性があり、実装と保守にかかるコストが増加します。」
他には以下が例示されているが非推奨とのこと
- DbContext と DbSet のモック化またはスタブ化
- データベースのフェイクとしてのインメモリプロバイダ
リポジトリパターンのメリット・デメリット
テストダブルの推奨はリポジトリパターンということなのでメリットとデメリットを検討したいと思います。
メリット
- テストの容易さ。(リポジトリのモック/スタブを用意すればアプリケーションのテストが行える)
- クリーンアーキテクチャ界隈で言われていること。
デメリット
- やはり開発コストが増えることでしょうか(とにかくコードが増える!)
- 層が増えたことによる悩ましい問題も色々あるようです。(この辺はクリーンアーキテクチャ、リポジトリでググると色々出てきます)
- リポジトリDB間のテストは必要
まとめ
なんかリポジトリパターン大変そうです。
私もめんどくせーとか思ってました。
しかし、直近でレポジトリパターン(クリーンアーキテクチャ)を取り入れたプロジェクトに参加したのですが、開発の規模によってはありかと思います。(コードが読みやすい!)
Microsoft的にもおすすめですしね。
テストありきの開発はライフサイクル全体で見れば明らかに優れているので、皆さんも検討してみてはいかがでしょうか。