2011-12-05 3 views
5

Estoy escribiendo un conjunto de pruebas de integración (Pruebas unitarias con MS Test que prueban que Entity Framework 4.2 persiste todas las clases correctamente en la base de datos).Entity Framework Integration pruebas DropCreateDatabaseAlways no borrar base de datos entre prueba

Cuando ejecuto todas las pruebas, una por una, todas funcionan bien. Cuando los ejecuto en un grupo, algunos de ellos fallan porque se devuelve la cantidad incorrecta de objetos, parece que el DB se limpia una vez al comienzo de las pruebas y no entre cada prueba, aunque puedo ver se crea un nuevo contexto y luego se elimina para cada prueba

¿Alguna idea?

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

Una versión reducida de la unidad/integración Pruebas de

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

}

Pasando a través de las pruebas que puedo ver el SetupTest y métodos TearDownTest siendo llamados pero que no parece limpiar la base de datos entre pruebas.

+0

bien Dokey parecería una respuesta (aunque me parece un poco hackish) es modificar el método TestCleanup para que caiga explícitamente y vuelva a crear la base de datos después de cada prueba [TestCleanup] public v oid TearDownTest() { if (_db.Database.Exists()) { _db.Database.Delete(); _db.Database.CreateIfNotExists(); } _db.Dispose(); _db = null; _dbResults.Dispose(); _dbResults = null; } –

+0

Bien, incluso mejor Respuesta: agregue una base de datos. Inicializar (forzar: verdadero); en el método TestInitialize. [TestInitialize] public void SetupTest() { _db = new myContext (_configSettings); _db.Database.Initialize (force: true); –

Respuesta

7

Bien, incluso mejor Respuesta: agregue una base de datos. Inicializar (forzar: verdadero); en el método 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

Esto funciona con una conexión normal (no MDF), ¿tiene alguna pista de por qué el mismo código no funcionará cuando la cadena de conexión incluye el parámetro 'AttachDBFilename'? Después de la llamada a '.Initialize (true)', EntityFramework elimina el archivo .MDF dentro de la ruta especificada, pero arroja una excepción SQL quejándose de que no se puede encontrar el archivo .MDF. ¿Tiene esto algo que ver con algunos indicadores/opciones de recuperación que dejé? ¡Esto parece un comportamiento bastante aleatorio para mí! – Dr1Ku

1

Puedo usar un ayudante para hacer este tipo de tareas:

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 
     } 
} 

y luego usarlo en la configuración de la prueba:

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