我使用 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/