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方法。

EF 4.1 Code First在使用Moq时没有初始化DB (DropCreateDatabaseAlways)

策略DropCreateDatabaseAlways<BaseUnitOfWork>正在寻找BaseUnitOfWork的精确类型匹配,而不是派生类型,也不是Mock<BaseUnitOfWork>。如果需要,则必须为模拟类型实现该策略的副本。

嘲弄上下文并同时期望数据库存在的意义是什么?mock的目的是消除对数据库的依赖(但它并不总是像预期的那样工作)。

因此,要么使用mock(包含所有问题的单元测试),要么使用包含真实上下文和集成测试的数据库。