我正在使用Entity Frameworc 4.1 Code First和Moq。我想测试数据库初始化程序。我还有从DbContext继承的抽象BaseUnitOfWork类(所以,为了测试它应该被模拟)。
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方法。
答案 0 :(得分:2)
策略DropCreateDatabaseAlways<BaseUnitOfWork>
正在寻找BaseUnitOfWork
的精确类型匹配,而不是派生类型,而不是Mock<BaseUnitOfWork>
。如果您需要它,您将必须为模拟类型实现策略的副本。
答案 1 :(得分:1)
模拟上下文的重点是什么,同时期望数据库存在?模拟的重点是消除对数据库的依赖(但will not always work as expected)。
因此要么使用mock(带有all its problems的单元测试),要么使用带有真实上下文和集成测试的数据库。