Ger*_*els 5 c# testing seed ef-code-first
我的问题和代码基于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();
}
}
Run Code Online (Sandbox Code Playgroud)
我还使用基类进行单元测试,初始化测试数据库,如下所示:
[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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
实际的单元测试如下所示:
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行测试时,获取savedDinner的Linq查询失败,并显示"ObjectContext实例已被释放,不能再用于需要连接的操作".例外.我无法理解为什么.
我在这里做的是一个可接受的模式,任何人都可以解释为什么这不起作用?
谢谢.
小智 3
今天早上我遇到了类似的问题。该问题是由种子方法中的 where 子句引起的。解决此问题的方法(目前)是重写以下内容:
var dinner = context.Dinners.ToList().Where(d => d.Country == "England").Single();
Run Code Online (Sandbox Code Playgroud)
虽然效率不高(所有对象都从数据库中检索,过滤将在内存中完成),但它确实解决了ObjectDisposedException我的单元测试中的问题。就我而言,我只有几个对象,所以我现在可以忍受它。
| 归档时间: |
|
| 查看次数: |
7389 次 |
| 最近记录: |