使用Moq时,EF 4.1 Code First不会初始化DB(DropCreateDatabaseAlways)

时间:2011-11-08 20:55:01

标签: c# entity-framework-4.1 ef-code-first moq code-first

我正在使用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方法。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

模拟上下文的重点是什么,同时期望数据库存在?模拟的重点是消除对数据库的依赖(但will not always work as expected)。

因此要么使用mock(带有all its problems的单元测试),要么使用带有真实上下文和集成测试的数据库。