2011-12-05 3 views
5

Sto scrivendo una serie di test di integrazione (test unitari con MS Test che testano che Entity Framework 4.2 sta mantenendo tutte le classi correttamente nel database).Test di integrazione di Entity Framework DropCreateDatabaseAlways non cancella il database tra test

Quando eseguo tutti i test uno per uno, tutti funzionano correttamente. Quando li eseguo in un gruppo - alcuni di essi falliscono quando viene restituito il numero sbagliato di oggetti - sembrerebbe che il db venga ripulito una volta all'inizio dei test e non tra ogni test - anche se riesco a vedere un nuovo contesto viene creato e quindi eliminato per ogni test

Qualsiasi idea?

public class EmptyDataInitializer : DropCreateDatabaseAlways<myContext> 
{ 
    protected override void Seed(myContext db) 
    { 
     //Do Nothing Create Empty Database 
     db.SaveChanges(); 
     base.Seed(db); 
    } 
} 

una versione ridotta del dispositivo/integrazione Test

[TestClass] 
public class PersistanceTests 
{ 
    //Creating two instances of our Repository so that we can make sure that we are reading from our database rather than in-memory 
    private myContext _db; 
    private myContext _dbResults; 
    private readonly ISettings _configSettings; 

    public PersistanceTests() 
    { 
     _configSettings = MockRepository.GenerateStub<ISettings>(); 
     _configSettings.ConnectionString = "data source=.;initial catalog=myContext_Test; Integrated Security=SSPI; Pooling=false"; 

     Database.SetInitializer(new EmptyDataInitializer()); 
    } 

    //This is called a single time after the last test has finished executing 
    [TestCleanup] 
    public void TearDownTest() 
    { 
     _db.Dispose(); 
     _db = null; 
     _dbResults.Dispose(); 
     _dbResults = null; 
    } 

    //This is called each time prior to a test being run 

    [TestInitialize] 
    public void SetupTest() 
    {   
     _db = new myContext(_configSettings); 
     _dbResults = new myContext(_configSettings); 

     // This forces the database to initialise at this point with the initialization data/Empty DB 
     var count = _db.Accounts.Count(); 
     var resultCount = _dbResults.Accounts.Count(); 
     if (count != resultCount) throw new InvalidOperationException("We do not have a consistant DB experiance."); 
    } 
    [TestMethod] 
    public void OrganisationPersistanceTest() 
    { 
     // Arrange 
     var apple = new Organisation { Name = "Apple" }; 
     _db.Organisations.Add(apple); 
     // Act 
     _db.SaveChanges(); 
     var organisationsCount = _dbResults.Organisations.Count(); 
     var organisationsAppleCount = _dbResults.Organisations.Where(a => a.Id == apple.Id).Count(); 
     var result = _dbResults.Organisations.FirstOrDefault(a => a.Id == apple.Id); 
     // Assert 
     Assert.IsTrue(organisationsCount == 1, string.Format("Organisations Count Mismatch - Actual={0}, Expected={1}", organisationsCount, 1)); 
     Assert.IsTrue(organisationsAppleCount == 1, string.Format("Apple Organisations Count Mismatch - Actual={0}, Expected={1}", organisationsAppleCount, 1)); 
     Assert.IsNotNull(result, "Organisations Result should not be null"); 
     Assert.AreEqual(result.Name, apple.Name, "Name Mismatch"); 
    } 

    //A Unit test 
    [TestMethod] 
    public void OrganisationWithNumberOfPeople_PersistanceTest() 
    { 
     // Arrange 
     var person = new Person { Firstname = "Bea" }; 
     var anotherPerson = new Person { Firstname = "Tapiwa" }; 
     var apple = new Organisation { Name = "Apple" }; 
     apple.AddPerson(person); 
     apple.AddPerson(anotherPerson); 
     _db.Organisations.Add(apple); 
     // Act 
     _db.SaveChanges(); 
     var organisationsCount = _dbResults.Organisations.Count(); 
     var organisationsAppleCount = _dbResults.Organisations.Where(a => a.Id == apple.Id).Count(); 
     var result = _dbResults.Organisations.FirstOrDefault(a => a.Id == apple.Id); 
     var peopleCountInOrganisation = result.People.Count(); 
     // Assert 
     Assert.IsTrue(organisationsCount == 1, string.Format("Organisations Count Mismatch - Actual={0}, Expected={1}", organisationsCount, 1)); 
     Assert.IsTrue(organisationsAppleCount == 1, string.Format("Apple Organisations Count Mismatch - Actual={0}, Expected={1}", organisationsAppleCount, 1)); 
     Assert.IsNotNull(result, "Organisations Result should not be null"); 
     Assert.AreEqual(result.People.Count, peopleCountInOrganisation, "People count mismatch in organisation Apple - Actual={0}, Expected={1}", peopleCountInOrganisation, 2); 
     Assert.AreEqual(result.Name, apple.Name, "Name Mismatch"); 
    } 

}

Facendo un passo attraverso le prove posso vedere la SetupTest e metodi TearDownTest chiamati ma che non sembra pulire il database tra i test.

+0

Va bene Dokey sembrerebbe una risposta (anche se mi sembra un po 'ritoccato) è quello di modificare il metodo TestCleanup in modo che cada e ricrea il database in modo esplicito dopo ogni test [TestCleanup] public v oid TearDownTest() { if (_db.Database.Exists()) { _db.Database.Delete(); _db.Database.CreateIfNotExists(); } _db.Dispose(); _db = null; _dbResults.Dispose(); _dbResults = null; } –

+0

Okay Risposta migliore - aggiungi un database.Initialize (force: true); nel metodo TestInitialize. [TestInitialize] public void SetupTest() { _db = new myContext (_configSettings); _db.Database.Initialize (force: true); –

risposta

7

Okay Risposta migliore: aggiungere un database.Initialize (force: true); nel metodo TestInitialize.

[TestInitialize] 
public void SetupTest() 
{   
    _db = new myContext(_configSettings); 
    _db.Database.Initialize(force: true); 
    _dbResults = new myContext(_configSettings); 

    // This forces the database to initialise at this point with the initialization data/Empty DB 
    var count = _db.Accounts.Count(); 
    var resultCount = _dbResults.Accounts.Count(); 
    if (count != resultCount) throw new InvalidOperationException("We do not have a consistant DB experiance."); 
} 
+0

Funziona con una connessione regolare (non MDF), hai un suggerimento sul perché lo stesso codice non funzionerà quando la stringa di connessione include il parametro 'AttachDBFilename'? Dopo la chiamata a '.Initialize (true)', EntityFramework elimina il file .MDF all'interno del percorso specificato, ma genera un'eccezione SQL che lamenta che il file .MDF non può essere trovato! Questo ha qualcosa a che fare con alcune bandiere di ripristino/opzioni che ho lasciato? Questo mi sembra un comportamento abbastanza casuale! – Dr1Ku

1

Io uso un aiuto per fare questo tipo di attività:

public abstract class TestingHelper 
{ 
     public static void ClearDatabase() 
     { 
      DatabaseContext myDbContext = new DatabaseContext(); 
      myDbContext.Database.Delete(); 
      myDbContext.Database.Create(); 
      //FillDatabase(lawyers); //<- OPTIONAL if you want to add rows to any type tables 
     } 
} 

E poi utilizzarlo nella configurazione del Test:

[SetUp] 
public void MyTests_SetUp() 
{ 
     TestingHelper.ClearDatabase(); 
}