簡體   English   中英

實體框架代碼優先:如何為數據進行單元測試

[英]Entity Framework Code First: How to seed a database for unit testing

我的問題和代碼基於Code First Entity Framework Unit Test Examples博客文章。 我正在使用SQL Compact 4.0,因此我的單元測試使用與博客文章中描述的類似的真實數據對實際數據庫運行。

我想在一些表中使用默認值為我的生產數據庫設定種子,但在運行我的單元測試時,我想添加其他數據並更新一些默認值。

我創建了一個自定義的Initializer類,它使用默認值為數據庫設定種子。 對於我的單元測試,我創建了另一個自定義初始化程序,它繼承自第一個執行測試特定種子和/或修改的初始化程序:

public class NerdDinnersInitializer : DropCreateDatabaseIfModelChanges<NerdDinners>
{
    protected override void Seed(NerdDinners context)
    {
        var dinners = new List<Dinner>
                          {
                              new Dinner()
                                  {
                                      Title = "Dinner with the Queen",
                                      Address = "Buckingham Palace",
                                      EventDate = DateTime.Now,
                                      HostedBy = "Liz and Phil",
                                      Country = "England"
                                  }
                          };

        dinners.ForEach(d => context.Dinners.Add(d));

        context.SaveChanges();
    }
}

public class NerdDinnersInitializerForTesting : NerdDinnersInitializer
{
    protected override void Seed(NerdDinners context)
    {
        base.Seed(context);

        var dinner = context.Dinners.Where(d => d.Country == "England").Single();
        dinner.Country = "Ireland";

        context.SaveChanges();
    }
}

我還使用基類進行單元測試,初始化測試數據庫,如下所示:

[TestClass]
public abstract class TestBase
{
    protected const string DbFile = "test.sdf";
    protected const string Password = "1234567890";
    protected NerdDinners DataContext;

    [TestInitialize]
    public void InitTest()
    {
        Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0", "",
                string.Format("Data Source=\"{0}\";Password={1}", DbFile, Password));
        Database.SetInitializer(new NerdDinnersInitializerForTesting());

        DataContext = new NerdDinners();
        DataContext.Database.Initialize(true);
    }

    [TestCleanup]
    public void CleanupTest()
    {
        DataContext.Dispose();

        if (File.Exists(DbFile))
        {
            File.Delete(DbFile);
        }
    }
}

實際的單元測試如下所示:

[TestClass]
public class UnitTest1 : TestBase
{
    [TestMethod]
    public void TestMethod1()
    {
        var dinner = new Dinner()
                          {
                              Title = "Dinner with Sam",
                              Address = "Home",
                              EventDate = DateTime.Now,
                              HostedBy = "The wife",
                              Country = "Italy"
                          };

        DataContext.Dinners.Add(dinner);
        DataContext.SaveChanges();

        var savedDinner = (from d in DataContext.Dinners
                           where d.DinnerId == dinner.DinnerId
                           select d).Single();

        Assert.AreEqual(dinner.Address, savedDinner.Address);
    }
}

當我運行測試時,獲取savedDinner的Linq查詢失敗,並顯示“ObjectContext實例已被釋放,不能再用於需要連接的操作”。 例外。 我無法理解為什么。

我在這里做的是一個可接受的模式,任何人都可以解釋為什么這不起作用?

謝謝。

今天早上我遇到了類似的問題。 問題是由種子方法中的where子句引起的。 這個(現在)的解決方法是重寫這個:

var dinner = context.Dinners.ToList().Where(d => d.Country == "England").Single(); 

盡管效率不高(所有對象都是從數據庫中檢索出來的,並且過濾將在內存中完成),但它確實在我的單元測試中解決了ObjectDisposedException 在我的情況下,我只有一些對象,所以我現在可以忍受它。

暫無
暫無

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

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