2014-09-19 2 views
3

EDITEDDatabase Initialization Запуск слишком поздно

Я бегу модульного тестирования (с использованием NUnit) для метода инициализации databsae. Я создал тест и заполнение базы данных с помощью тестового примера с помощью этого:

[TestFixtureSetUp] 
    public void SetUp() 
    { 
     //select database 
     Database.DefaultConnectionFactory = new SqlConnectionFactory(connectionString); 
     database = new POSDatabaseContext(connectionString); 

     //drop database and recreate 
     string query = "ALTER DATABASE [POS] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;"; 
     database.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, query); 
     database.Database.Delete(); 
     database.Database.Create(); 

     //add seed value to test against 
     database.Metadata.Add(new Metadata { 
      ID = "META", 
      IsInitialized = false, 
      testBool = true, 
      TimeCreated = DateTime.Now, 
      TimeEdited = DateTime.Now 
     }); 
     database.SaveChanges(); 
    } 

Я затем запустить тестовый метод, который заключается в следующем:

[Test] 
    public void InitializeDatabaseTestWithMatchingModel() 
    { 
     //set initializer for data context to test it, and run it 
     Database.SetInitializer<POSDatabaseContext>(new 
      CustomDropCreateDatabaseWithMatchingModelTest()); 
     database.Database.Initialize(true); 

     //use the metadata table to check if it was run correctly 
     //if metadata exist, which it should 
     if(database.Metadata.Any(s => s.ID == "META")) 
     { 
      Metadata actual = database.Metadata.Single(s => s.ID == "META"); 
      Assert.IsTrue(actual.IsInitialized); 
     } 
     else 
      throw new Exception("The Database was not seeded correctly for the test"); 
    } 

Для того, чтобы проверить мои пользовательские Initializer я сделал класс, который наследует от него, я мог бы использовать метод Seed(), чтобы сделать некоторые данные, которые я мог бы проверить. Этот класс:

А класс он был получен от:

//This file contains custom versions of the built in 
//database intializer classes in which an SQL Statement 
//is run to stop all connections to the database so that 
//when the database is dropped, a database in use 
//exception is not thrown. 
public class CustomDropCreateDatabaseIfModelChanges<Context> 
    : IDatabaseInitializer<Context> where Context : DbContext 
{ 
    public void InitializeDatabase(Context context) 
    { 
     if (context.Database.Exists()) 
     { 
      if (!context.Database.CompatibleWithModel(true)) 
      { 
       string query = "ALTER DATABASE [POS] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;"; 
       context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, query); 
       context.Database.Delete(); 
       context.Database.Create(); 
      } 
      //else do nothing and continue 
     } 
     else context.Database.Create(); 

     //run seed method 
     Seed(context); 
    } 

    //OVERIDE ME 
    //this method seeds the database with data 
    protected virtual void Seed(Context context) { } 
} 

Проблема я, кажется, имея в том, что Initilization не не работает до тех пор, после утверждают. Я проверил значения метаданных, а значения - значения метода SetUp(). Я также проверил, что объект помечен как измененный, прежде чем SaveChanges() вызывается в методе, который я тестирую. Однако этот метод, безусловно, работает, потому что база данных отражает значения из метода.

Первоначальная проблема, с которой я думал, заключалась в том, что свойство IsInitialized возвращалось как неправильное значение, так как оно было 1 в базе данных, но я получал false в коде.

+0

Вы пытались установить еще одно свойство boolean? Это может привести к пониманию, если вы пропустили что-нибудь в первый раз. – Archangel33

+0

Я думал об этом, но я не уверен, как я буду использовать его. Это сложно, потому что я бы хотел, чтобы его использовали по-другому, чтобы проверить его. Я думаю. – some1one

+0

Извините, отредактированный, я пропустил это при публикации кода. Строка в моем коде одинакова. – some1one

ответ

1

Изменить Assert.AreEqual(true, на Assert.IsTrue(, так как true может иметь разные формы между типами. Как вы заметили, в базе данных было закодировано 1, что может не совпадать точно.

Вы можете проверить, правильно ли обновлен контекст перед утверждением SaveChanges(): сначала выполните утверждение на TimeEdited. (Замените DateTime.Now с некоторым постоянным значением, которое сначала сравнивается легче).

+0

Я выводил на консоль с логическим значением и был ложным. Поэтому первая часть - это не то, почему она не работает, но я начну использовать этот формат независимо. Для второй части я думаю, что вы можете быть правы. – some1one

+0

Хорошо, поэтому я заменил DateTime.Now с DateTime.UTC. Как раз перед утверждением, это все еще DateTime.Now, но в базе данных это DateTime.UTC после теста. Поэтому метод, который я тестирую, работает, но не до утверждения, и я не уверен, почему. Я должен, вероятно, опубликовать полный код сейчас, как мне это сделать? Я не уверен, что хочу отредактировать свое оригинальное сообщение, чтобы вопрос не изменился, а остальные комментарии не выглядят вне контекста. – some1one

+0

Просто отредактируйте исходное сообщение и отметьте его отредактированным. – Pieter21

0

В верхней части моего тестового класса у меня есть:

[TestFixture] 
public class CustomDropCreateDatabaseIfModelChangesTest 
{ 
    protected const string connectionString = 
     "Data Source=SABERTOOTH\\POS;Initial Catalog=POS;Integrated Security=true;Pooling=false"; 
    protected POSDatabaseContext database; 

.... 

} 

я изменил тест, чтобы использовать новый DbContext, как так:

[Test] 
    public void InitializeDatabaseTestWithMatchingModel() 
    { 
     //set initializer for data context to test it, and run it 
     Database.SetInitializer<POSDatabaseContext>(new CustomDropCreateDatabaseWithMatchingModelTest()); 
     database.Database.Initialize(true); 

     POSDatabaseContext newContext = new POSDatabaseContext(connectionString); 

     //use the metata table to check if it was run correctly 
     //if metadata exist, which it should 
     if(newContext.Metadata.Any(s => s.ID == "META")) 
     { 
      Metadata actual = newContext.Metadata.Single(s => s.ID == "META"); 

      Assert.IsTrue(actual.IsInitialized); 
     } 
     else 
      throw new Exception("The Database was not seeded correctly");   
    } 

Так получается, что Pieter21 было правильным по какой-то причине контекст не обновлялся, и нужно было создать новый контекст. Однако я не знаю, почему.

Смежные вопросы