EF Core アプリケーションのテスト

テストは、ほぼすべての種類のアプリケーションにとって重要な問題です。それを実施することで、アプリケーションが正常に動作していることを確認でき、また、将来的にその動作に不具合が生じないかどうかをすぐに把握できます。 テストはコードの設計方法に影響を与える場合があるため、テストを早期に計画すること、アプリケーションの進化に合わせて適切なカバレッジを確保することを強くお勧めします。 この概要セクションでは、EF Core を使用したアプリケーションに対する各種のテスト戦略について概要を簡単に説明します。

データベースを必要とする (または必要としない)

EF Core アプリケーションのテストを作成する際には、1 つ基本的な決定を行う必要があります。それは、アプリケーションの場合と同様にテストに運用データベースシステムを含めるかどうか、あるいは運用データベース システムをテストダブルに置き換えてそれに対してテストを実施するかどうかということです。 EF Core コンテキストでのテスト ダブルの例としては、主に SQLite インメモリ モードメモリ内プロバイダーの 2 つがあります。

さまざまなアプローチの比較および分析の詳細については、「テスト戦略の選択」を参照してください。 さまざまなオプションを理解するのに役立つように、項目ごとの簡単な要約を以下に示します。

  • 開発者は、運用データベース システムに対してテストを実施することは難しく時間がかかると考えているため、避ける傾向にあります。 これは Microsoft の経験上、必ずしも真実ではありません。このアプローチを試してみることをお勧めします。「運用データベース システムに対するテスト」に、それを確実かつ効率的に実施するための手法が説明されています。 通常はご利用のデータベースに対して少なくともいくつかのテストを作成する必要があります。これは、ご利用のアプリケーションが運用データベースに対して実際に機能することを確認するためです。そのデータベースを含まないテストでは、テストできる範囲が制限される可能性があります (以下を参照)。
  • メモリ内プロバイダーは、多くの重要な点で、実際のデータベースとは動作が異なります。 それを使用した場合、まったくテストできない機能 (トランザクション、生 SQL など) がある一方で、運用データベースとは異なる動作をする可能性のある機能 (クエリでの大文字と小文字の区別など) もあります。 インメモリは、制約のあるシンプルなクエリ シナリオで使用できますが、非常に制限されるため、使用することはお勧めしません。
    • クエリに対して DbSet をモックすることは複雑かつ困難であり、インメモリ アプローチと同じ欠点があります。これもお勧めしません。
  • SQLite インメモリ モードを使用すると、運用リレーショナル データベースとの互換性が向上します。これは、SQLite 自体が本格的なリレーショナル データベースであるためです。 ただし、SQLite と運用データベースとの間には重要な相違点がいくつかあり、一部の機能についてはまったくテストすることができません (EF.Function に対するプロバイダー固有のメソッドなど)。
  • 運用データベース システムのすべての機能に対して信頼性の高いテスト ダブルを使用できるテストアプローチの場合、アプリケーションにリポジトリ レイヤーを導入することが可能です。 これにより、EF Core を完全にテストから除外し、リポジトリを完全にモックすることができます。ただし、これによってアプリケーションのアーキテクチャが大きく変化する可能性があり、実装と保守にかかるコストが増加します。

参考資料

詳細については、「テスト戦略の選択」を参照してください。 実装のガイドラインとコードサンプルについては、「運用データベースシステムに対するテスト」と「運用データベースシステムを使用しないテスト」を参照してください。