簡體   English   中英

實體框架集成測試無法運行通過單個測試的多個測試[Resharper,NUnit,EF6]

[英]Entity Framework Integration tests failing running multiple tests that are singularly passing [Resharper, NUnit, EF6]

我在使用Resharper 8.2,NUnit 2.6.4運行Integration Test時出現不一致的行為。 根據我選擇的測試數量,有時所有測試都會通過,有時只是一次測試和最后一次測試。 相反,如果我單獨運行每個測試,則它們全部通過。

在這個原型中,我使用了一個基礎測試類,該類使用現有的存儲過程擦除數據庫(避免此步驟結果不變),然后初始化數據。

在用於為基於構建器和實體的數據庫設置種子的類的下面。

public class DefaultTestData<TB, TE> : ITestData where TB:BaseBuilder<TB, TE>
{
    public void Seed(DbContext context)
    {
        context.Set(typeof (TE)).Add(((TB) Activator.CreateInstance(typeof (TB))).Build());
        context.Set(typeof (TE)).Add(((TB) Activator.CreateInstance(typeof (TB))).Build());
        context.SaveChanges();
    }
}

基本測試類,由所有測試類繼承。

[TestFixture]
public abstract class BaseTest
{
    protected FmsDbContext Context = null;

    public abstract ITestData InitializeData();

    [Test]
    public abstract void Mapping();

    [Test]
    public abstract void Delete();

    [SetUp]
    public virtual void SetupInitialData()
    {
        var data = InitializeData();
        Context = new FmsDbContext();
        // Context.Database.Initialize(true); -- Using initialize One or Zero test runs

        if (data != null)
        {
            Database.SetInitializer(new TestDataInitializer(data));
        }
    }

    [TearDown]
    public virtual void Teardown()
    {
        if (Context != null)
        {
            Context.Dispose();
        }
    }
}

定制數據庫初始化程序類

public class TestDataInitializer : IDatabaseInitializer<FmsDbContext>
{
    private readonly ITestData _data;

    public TestDataInitializer(ITestData data)
    {
        _data = data;
    }

    private void Seed(DbContext context)
    {
        if(_data != null)
            _data.Seed(context);
    }

    public void InitializeDatabase(FmsDbContext context)
    {
        context.Database.ExecuteSqlCommand("EXEC [dbo].[uspWipeDatabase]");
        Seed(context);
    }
}

public interface ITestData
{
    void Seed(DbContext context);
}

簡單測試

[TestFixture]
public class TagTest : BaseTest
{
    public override ITestData InitializeData()
    {
        return new DefaultTestData<TagBuilder, Tag>();
    }

    [Test]
    public override void Mapping()
    {
        var tag = Context.Tags.FirstOrDefault();
        Assert.NotNull(tag);
    }

    [Test]
    public override void Delete()
    {
        var initialCount = Context.Tags.Count();
        var tag = Context.Tags.FirstOrDefault();
        Context.Tags.Remove(tag);
        Context.SaveChanges();

        Assert.AreEqual(Context.Tags.Count(), initialCount - 1);
    }
}

任何想法?

編輯:

  • 我添加了一個簡單的測試示例
  • 使用NUnit代理運行測試我具有相同的行為
  • 調試似乎僅完成一次播種
  • 使用SQL事件探查器,我可以看到數據庫重置和種子啟動僅完成一次

@Steve Fenton測試失敗,因為數據庫為空,因此無法讀取和刪除數據的測試。

@Gert Arnold

我找到了解決方案,(畢竟)很明顯。 您可以在下面看到最終的解決方案。

關鍵是Database.SetInitializer ,它配置EF使用已注冊的IDatabaseInitializers初始化數據庫。

EF6允許您使用Context.Database.Initialize(true); 強制數據庫運行所有初始化程序。

設置為True的boolean參數將強制運行初始化程序,即使已針對當前上下文運行了這些初始化程序。

[SetUp]
public virtual void SetupInitialData()
{
    var data = InitializeData();
    Context = new FmsDbContext();

    if (data != null)
    {
        Database.SetInitializer(new TestDataInitializer(data));
    }

    Context.Database.Initialize(true);
}

有關更多信息,請訪問: http : //msdn.microsoft.com/zh-cn/library/system.data.entity.database.initialize%28v=vs.113%29.aspx

我找到了解決方案,(畢竟)很明顯。 您可以在下面看到最終的解決方案。

關鍵是Database.SetInitializer ,它配置EF使用已注冊的IDatabaseInitializers初始化數據庫。

EF6允許您使用Context.Database.Initialize(true); 強制數據庫運行所有初始化程序。

設置為True的boolean參數將強制運行初始化程序,即使已針對當前上下文運行了這些初始化程序。

[SetUp]
public virtual void SetupInitialData()
{
    var data = InitializeData();
    Context = new FmsDbContext();

    if (data != null)
    {
        Database.SetInitializer(new TestDataInitializer(data));
    }

    Context.Database.Initialize(true);
}

有關更多信息,請訪問: http : //msdn.microsoft.com/zh-cn/library/system.data.entity.database.initialize%28v=vs.113%29.aspx

暫無
暫無

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

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