c# - Entity Framework 集成测试无法运行多个单独通过的测试 [Resharper、NUnit、EF6]

标签 c# nunit resharper integration-testing entity-framework-6

我使用 Resharper 8.2、NUnit 2.6.4 运行集成测试时出现不一致的行为。 根据我选择的测试数量,有时所有都通过,有时只是第一个和最后一个。 相反,如果我单独运行每个测试,它们都会通过。

在此原型(prototype)中,我使用了一个基本测试类,该类使用现有存储过程删除数据库(避免这一步,结果不会改变),然后初始化数据。

下面的类用于为基于构建器和实体的数据库提供种子。

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 探查器,我可以看到数据库重置和种子在开始时仅完成一次

@史蒂夫·芬顿 测试失败,因为数据库为空,因此读取和删除数据的测试不起作用。

@格特·阿诺德 没有。

解决方案

我找到了解决方案,(毕竟)非常明显。 下面您可以看到最终的解决方案。

关键是 Database.SetInitializer,它配置 EF 以使用注册的 IDatabaseInitializers 初始化数据库。

EF6 允许您使用 Context.Database.Initialize(true); 来强制数据库运行所有初始化程序。

bool 参数设置为 True 强制运行初始化程序,即使这些初始化程序已经在当前上下文中运行。

[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/en-us/library/system.data.entity.database.initialize%28v=vs.113%29.aspx

最佳答案

我找到了解决方案,(毕竟)非常明显。下面您可以看到最终的解决方案。

关键是 Database.SetInitializer,它配置 EF 以使用注册的 IDatabaseInitializers 初始化数据库。

EF6 允许您使用 Context.Database.Initialize(true); 来强制数据库运行所有初始化程序。

bool 参数设置为 True 强制运行初始化程序,即使这些初始化程序已经在当前上下文中运行。

[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/en-us/library/system.data.entity.database.initialize%28v=vs.113%29.aspx

关于c# - Entity Framework 集成测试无法运行多个单独通过的测试 [Resharper、NUnit、EF6],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27755864/

相关文章:

c# - 什么是好的、免费的 C# 单元测试覆盖工具?

javascript - 使用 Jasmine 进行 VS、Resharper、Karma 和 AngularJS 模板单元测试

c# - Java 中的内存

c# - 如果 C# 规范将它们称为简单类型,为什么 Type 类有一个名为 IsPrimitive() 的方法?

c# - NUnit 无法识别包含数组的 TestCase

c# - 使用隐式类型

c# - 创建通用类型以在 Resharper 插件中查找实现

c# - P2P 真的是无服务器的吗?

c# - 使用C#在页面上编写ASP代码

c# - NUnit:如何在多个对象上运行测试类 - 比 TestCaseSourceAttribute 更好的选择?