6

Trying to do some unit testing with EF 4.1 code first. I have my live db (SQL Server) and my unit test DB( Sql CE). After fighting (and losing) with EF, Sql CE 4.0 and Transaction support I decided the simplest way to run my test was to:

  1. Create Db
  2. Run Test
  3. Delete Db
  4. Rinse and repeat

I have my [Setup] and [TearDown] functions:

[SetUp]
public void Init()
{
    System.Data.Entity.Database.SetInitializer(new MyTestContextInitializer());
    _dbContext = ContainerFactory.Container.GetInstance<IContext>();
    _testConnection = _dbContext.ConnectionString;
}

[TearDown]
public void Cleanup()
{
    _dbContext.Dispose();
    System.Data.Entity.Database.Delete(_testConnection);
}

Issue is that System.Data.Entity.Database.SetInitializer does not call MyTestContextInitializer after the first test.

Hence the 2nd test then fails with:

System.Data.EntityException : The underlying provider failed on Open.
----> System.Data.SqlServerCe.SqlCeException : The database file cannot be found. Check the path to the database

TIA for any pointers

ozczecho
  • 8,649
  • 8
  • 36
  • 42

3 Answers3

7

I got around this by calling 'InitializeDatabase' manually. Like so:

   [SetUp]
    public void Init()
    {

        var initializer = new MyTestContextInitializer();
        System.Data.Entity.Database.SetInitializer(initializer);

        _dbContext = ContainerFactory.Container.GetInstance<IContext>();
        initializer.InitializeDatabase((MyTestContext)_dbContext);

        _testConnection = _dbContext.ConnectionString;
    }

    [TearDown]
    public void Cleanup()
    {
        System.Data.Entity.Database.Delete(_testConnection);

        _dbContext.Dispose();
    }

I think it may be a bug with EF 4.1 RC.

ozczecho
  • 8,649
  • 8
  • 36
  • 42
  • Lovely, that's helped me sort out what I thought was locking of the DB file (CE 4) between test fixtures. +1 :) – Sean Kearon Jun 11 '11 at 16:47
  • Brilliant! I had exactly this issue, with EF5 no less, and have been stuck on it a while. This fixed it for me, thankyou. – Justin Harvey Oct 04 '12 at 10:14
2

It's not a bug, the initializer set with

System.Data.Entity.Database.SetInitializer

is only called when the context is created for the first time in the AppDomain. Hence, since you're running all your tests in a single AppDomain, it's only called when the first test is ran.

juanagui
  • 807
  • 9
  • 8
1

It took me almost a day to find out what caused my strange unittest behaviour: the database connection stayed open or the database was not created with a every new test. I searched everywhere for the root of the cause: MSTest (no Admin rights or where working copies of files somehow deleted?), SQL Server Express/CE (login failure?), Unity (objects not disposed?) or Entity Framework (no proper database initialization?). It turned out to be EF. Thanks a lot for the answer!