EF 4.1 Code First在使用Moq时没有初始化DB (DropCreateDatabaseAlways)
本文关键字:初始化 DB DropCreateDatabaseAlways Moq Code First EF | 更新日期: 2023-09-27 18:13:56
我使用Entity frameworkc 4.1 Code First and Moq。我想测试数据库初始化器。我也有抽象的BaseUnitOfWork类继承自DbContext(所以,测试它应该被嘲笑)。
public abstract class BaseUnitOfWork : DbContext, IUnitOfWork
{
...
public IDbSet<User> Users
{
get
{
return Set<User>();
}
}
...
}
用户是简单的POCO,有三个属性:Id, Login, Password。
下面是DbInitializer的代码:
public class BaseDbInitializer : DropCreateDatabaseAlways<BaseUnitOfWork>
{
protected override void Seed(BaseUnitOfWork context)
{
base.Seed(context);
context.Set<User>().Add(new User { Login = "admin", Password = "1" });
context.SaveChanges();
}
}
我试着用下一个测试来测试这个初始化器(使用了NUnit):
[TestFixture]
public class BaseDbInitializerTests
{
private BaseUnitOfWork _baseUnitOfWork;
[TestFixtureSetUp]
public void Init()
{
Database.SetInitializer(new BaseDbInitializer());
_baseUnitOfWork = new Mock<BaseUnitOfWork>(Consts.ConnectionStringName).Object;
_baseUnitOfWork.Database.Initialize(true);
}
[TestFixtureTearDown]
public void CleanUp()
{
_baseUnitOfWork.Dispose();
Database.Delete(Consts.ConnectionStringName);
}
[Test]
public void ShouldInitializeBaseDb()
{
var repository = new Mock<BaseRepository<User>>(_baseUnitOfWork).Object;
var firstUserInDb = repository.FindBy(x => x.Login == "admin" && x.Password == "1").SingleOrDefault();
Assert.That(firstUserInDb, Is.Not.Null);
Assert.That(firstUserInDb.Login, Is.EqualTo("admin"));
Assert.That(firstUserInDb.Password, Is.EqualTo("1"));
}
}
不幸的是,BaseDbInitializer类的Seed方法似乎没有执行。DB正在重新创建,但是没有任何记录,我试图调试这个测试,并且在调试会话期间执行了Seed方法。
策略DropCreateDatabaseAlways<BaseUnitOfWork>
正在寻找BaseUnitOfWork
的精确类型匹配,而不是派生类型,也不是Mock<BaseUnitOfWork>
。如果需要,则必须为模拟类型实现该策略的副本。
嘲弄上下文并同时期望数据库存在的意义是什么?mock的目的是消除对数据库的依赖(但它并不总是像预期的那样工作)。
因此,要么使用mock(包含所有问题的单元测试),要么使用包含真实上下文和集成测试的数据库。