簡體   English   中英

在實體框架中使用 DbSet 而不是 IDbSet 模擬數據庫上下文類

[英]Mocking database context class with DbSet instead of IDbSet in Entity Framework

我正在開發一個 Asp.Net mvc 應用程序。 我正在對我的應用程序進行單元測試。 我使用 Moq 來模擬對象。 在我的測試中,我需要模擬數據庫上下文及其 DbSet。 我可以模擬數據庫上下文並進行測試。 但問題是我必須從改變DbSet<Entity>實體來IDbSet<Entity>在上下文類實體。

這是我如何模擬上下文類的示例

[TestMethod]
    public void GenerateItemCode_IncreaseDigit()
    {
        var data = new List<Item>{
            new Item{
                Id = 2,
                ItemCode = "CD345678"
            }
        }.AsQueryable();
        var dbSetMock = new Mock<IDbSet<Item>>();
        dbSetMock.Setup(m => m.Provider).Returns(data.Provider);
        dbSetMock.Setup(m => m.Expression).Returns(data.Expression);
        dbSetMock.Setup(m => m.ElementType).Returns(data.ElementType);
        dbSetMock.Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

        var storeContext = new Mock<StoreContext>();
        storeContext.Setup(x => x.Items).Returns(dbSetMock.Object);

        ItemRepo itemRepo = new ItemRepo(storeContext.Object);
        string itemCode = itemRepo.GenerateItemCode();
        Assert.AreEqual(itemCode, "CD345679");
    }

這是上下文類

 public class StoreContext : DbContext, IDisposable
    {
        public StoreContext():base("DefaultConnection")
        {

        }

         public virtual IDbSet<Item> Items { get; set; }
 protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {

        }
    }

當我使用 IDbSet 而不是 DbSet 時,我的應用程序的性能會下降。 因為我不能使用如下

context.Items.Include("Promotions")//Cannot use Include with IDbSet
context.Items.AddRange(items)//cannot use AddRange with IDbSet
context.Items.RemoveRange(items)//cannot with IDbSet

所以我在上下文類中從 IDbSet 更改為 DbSet,如下所示

public virtual DbSet<Item> Items { get; set; }

然后單元測試開始拋出錯誤。 因為上下文類的項目不能用我嘲笑的方式來嘲笑。 下面是錯誤截圖。

在此處輸入圖片說明

所以我在單元測試中從 IDbSet 改為 DbSet。 然后錯誤變成這樣。

在此處輸入圖片說明

如何為單元測試模擬上下文類的 DbSet 實體?

問題更新后,我可以重現您的問題。 您只是忘記轉換到正確的接口 IQueryable:

  var dbSetMock = new Mock<DbSet<Item>>();
      dbSetMock.As<IQueryable<Item>>().Setup(m => m.Provider).Returns(data.Provider);
      dbSetMock.As<IQueryable<Item>>().Setup(m => m.Expression).Returns(data.Expression);
      dbSetMock.As<IQueryable<Item>>().Setup(m => m.ElementType).Returns(data.ElementType);
      dbSetMock.As<IQueryable<Item>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());

如果您想知道為什么必須強制轉換才能設置提供程序,那是因為 IQueryable 的顯式接口實現。 更多信息:https ://msdn.microsoft.com/en-us/library/aa288461(v=vs.71).aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM