2014-09-19 112 views
3
太晚

EDITED数据库初始化运行所

我运行了databsae初始化方法的单元测试(使用NUnit)。我设置的测试,并使用该种子与测试实例数据库:

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

为了测试我的自定义初始化程序我做了一个继承自它的类我可以使用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) { } 
} 

这个问题我似乎有是至开机不运行,直到断言之后。我已经检查了元数据的实际值,这些值是来自SetUp()方法的值。我还检查了在我测试的方法中调用SaveChanges()之前,对象被标记为已修改。但是,该方法肯定是在运行,因为数据库反映了该方法的值。

原以为我遇到的问题是IsInitialized属性被返回为错误的值,因为它在数据库中为1,但我在代码中得到了错误。

+0

您是否尝试过设置另一个布尔属性?如果你第一次错过任何东西,这可能会导致一个洞察。 – Archangel33 2014-09-19 14:20:40

+0

我正在考虑这样做,但我不知道如何使用它。这很困难,因为我希望它有不同的用法来测试它。我认为。 – some1one 2014-09-19 14:24:58

+0

对不起,编辑过,我在发布代码时错过了这些。该字符串在我的代码中是相同的。 – some1one 2014-09-19 14:31:37

回答

1

Assert.AreEqual(true,改为Assert.IsTrue(,因为true可以在类型之间有不同的形式。正如您注意到的那样,它在数据库中编码为1,可能不完全匹配。

您可以检查SaveChanges()是否在正确断言之前更新上下文:首先在TimeEdited上执行断言。 (将DateTime.Now替换为一些比较容易的常数值)。

+0

我输出到控制台的布尔值,它是假的。所以第一部分不是为什么它不工作,但我会开始使用该格式。对于第二部分,我认为你可能是对的。 – some1one 2014-09-19 14:52:48

+0

好吧,我用DateTime.UTC替换了DateTime.Now。就在断言之前,它仍然是DateTime.Now,但在数据库中它是测试后的DateTime.UTC。所以我正在测试的方法正在运行,但不是在assert之前,我不知道为什么。我应该现在可以发布我的完整代码,我应该怎么做呢?我不确定我想编辑我的原始文章,因此问题不会改变,其他评论也不会看上下文。 – some1one 2014-09-19 15:15:18

+0

只需编辑原始文章并将其标记为已编辑。 – Pieter21 2014-09-19 15:20:54

0

在我的测试类的顶部,我有:

​​

我已经改变了测试,使用新的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是正确的由于某种原因,上下文没有得到更新,并且必须创建新的上下文。但我不知道为什么。