Entity Frameworkでストアドプロシージャを呼び出す関数があります。
public async Task<List<Entity>> GetEntity(int id)
{
var param = new SqlParameter("@id", id);
return await myContext.Database
.SqlQuery<MyEntity>("[myStoredProcedure] @id", param)
.ToListAsync();
}
そして、私は努力を使用して単体テストを作成したいと思います。私は既に(私の文脈に基づいて)データベースをシミュレートするEffort(そしてNMemoryデータベース)、各ユニットテストのInitialize
で次のようになっています:
[TestInitialize]
public void Initialize()
{
Effort.Provider.EffortProviderConfiguration.RegisterProvider();
EffortProviderFactory.ResetDb()
using (var context = new MyContext("PWET"))
{
context.Database.CreateIfNotExists();
context.Constructeurs.Add(new Constructeur { Nom = "Zebra" });
context.Constructeurs.Add(new Constructeur { Nom = "Joya" });
context.SaveChanges();
}
}
EffortProviderFactory
は次のEffortProviderFactory
です。
public class EffortProviderFactory : IDbConnectionFactory
{
private static DbConnection _connection;
private readonly static object _lock = new object();
public static void ResetDb(){
lock (_lock){
_connection = null;
}
}
public DbConnection CreateConnection(string nameOrConnectionString)
{
lock (_lock){
if (_connection == null)
_connection = Effort.DbConnectionFactory.CreateTransient();
return _connection;
}
}
}
私はそのようなストアドプロシージャの作成を追加するテスト:
[TestInitialize]
public void Initialize()
{
Effort.Provider.EffortProviderConfiguration.RegisterProvider();
EffortProviderFactory.ResetDb()
using (var context = new MyContext("PWET"))
{
context.Database.CreateIfNotExists();
context.Database.ExecuteSqlCommand(@"
CREATE PROCEDURE [dbo].[myStoredProcedure]
@id INT = 0
AS
BEGIN
SELECT foo
FROM bar
WHERE foo.Id = @id
ORDER BY foo.Id;
END");
}
}
しかし、それはNotSupportedException
スローします。どうすればいいですか、何が最良の方法ですか?
Effortは、 DbContext
インスタンスに個人的に所有されているテンポラリデータベース(新しいコンテキスト、新しいデータベース、テスト対話なし)を提供するファイルベースのインメモリデータベースプロバイダです。それは良い部分です。
もちろん、欠点は、本格的なデータベースエンジンではないことです。したがって、一般的なSQLダイアレクト(t-SQLやPL-SQLなど)で記述されたストアドプロシージャはサポートされません 。 Effort(つまりNMemory)がプロシージャをストアしている限り、それはStoredProcedure
コンストラクタから明らかなように、ストアドIQueryable
に過ぎません。 t-SQLストアドプロシージャにリモートで関連すること。
データアクセス層コードでストアドプロシージャをテストする唯一の方法は、非常に良いアイデアです。統合テストを作成することです。統合テストを互いに独立させるためには、おおよそ2つのアプローチがあります。
テストごとに新しいデータベースを作成/シードする
テストケースを持つ既存のデータベースを使用し、各テスト後に、たとえばTransactionScopeを使用して変更をロールバックします。
統合テストは単体テストと同じくらい速くなることは決してなく、単体テストを補完するに過ぎませんが、データ層に関する私自身のコーディング慣習では、テストスイートの第一人者となっています。私にとっては、スピードよりも正確さが重要です。