EF InMemory測試

如何使用EF InMemory做測試,達到隨用隨丟

EF Core 提供了一種測試方式in-memory 方便隨用隨丟,提高測試速度
使用上尚有部分限制,無法完全解除,例如View、SP等等,不適合in-memory中做測試
其餘皆可使用Linq語法在in-memory中測試

分享幾個使用上需要面臨的問題以及解法

  1. Idenetiy欄位自動新增
  2. Transaction警告
  3. DB只能共用

Identity欄位自動新增 

使用InMemoryIntegerValueGenerator

EF Core 6 寫法,EF Core 6使用EF Core 5的寫法會報錯

       protected override void OnModelCreating(ModelBuilder modelBuilder)
       {
           base.OnModelCreating(modelBuilder);
           modelBuilder.Entity<Test_Table>(entity =>
           {
               entity.Property(e => e.Id).HasValueGenerator((p, e) => new InMemoryIntegerValueGenerator<long>(p.GetIndex()));
               entity.Property(e => e.CreateTime)
                   .HasColumnType("datetime")
                   .HasDefaultValueSql("(getdate())");
           });
       }

EF Core 5寫法

       protected override void OnModelCreating(ModelBuilder modelBuilder)
       {
           base.OnModelCreating(modelBuilder);
           modelBuilder.Entity<Test_Table>(entity =>
           {
               entity.Property(e => e.Id).HasValueGenerator<InMemoryIntegerValueGenerator<long>>();
               entity.Property(e => e.CreateTime)
                   .HasColumnType("datetime")
                   .HasDefaultValueSql("(getdate())");
           });
       }

Transaction警告

 增加忽略InMemoryEventId.TransactionIgnoredWarning

var fakedb = new FakeDb(new DbContextOptionsBuilder<TestDb>()
.UseInMemoryDatabase(databaseName: "Test")
.ConfigureWarnings(w => w.Ignore(InMemoryEventId.TransactionIgnoredWarning))
.Options
);

DB只能共用

創建時即便DB名稱改成GUID亦會取得同一份DB,貌似無法隔離測試


另有極少Linq語法使用上會有問題的情況,要請自行留意
例如 
相同Linq語法,連線實體DB時無異常,in-memory卻報錯
Where 條件的先後寫法,導致查詢結果資料不相同

資料參考來源

  1. 官網文件