1

I'm using Entity Frameworc 4.1 Code First and Moq. And I want to test database initializer. Also I have the abstract BaseUnitOfWork class which inherited from DbContext (so, for testing it should be mocked).

public abstract class BaseUnitOfWork : DbContext, IUnitOfWork
{
    ...
        public IDbSet<User> Users
        {
            get
            {
                return Set<User>();
            }
        }
    ...
}

User is simple POCO with three properties: Id, Login, Password.

And here is the code of the 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();
    }
}

I'm trying to test this initializer with the next test (NUnit is used):

[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"));
    }
}

Unfortunately it seems like Seed method of the BaseDbInitializer class doesn't execute. DB is recreating, but there is no any records, and I tried to debug this test and Seed method was executed during debug session.

msi
  • 3,202
  • 4
  • 27
  • 37

2 Answers2

2

The strategy DropCreateDatabaseAlways<BaseUnitOfWork> is looking for an exact type match of BaseUnitOfWork, not a derived type, and not Mock<BaseUnitOfWork>. If you need it, you'll have to implement a copy of the strategy for the mocked type.

Teoman Soygul
  • 25,584
  • 6
  • 69
  • 80
1

What is the point of mocking context and in the same time expecting database to exists? The point of mocking is removing dependency on the database (but it will not always work as expected).

So either use mock (unit test with all its problems) or database with real context and integration test.

Community
  • 1
  • 1
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670