我已经在这个问题上进行了广泛的搜索,并且找到了零结果,这正是我想要做的。
从高层次来看,这就是我想要做的:
这有什么意义?
好吧,它在上面的断言中有相当多的描述;数据的完整性。此项目中的迁移使用Database.Migrate()
在应用程序启动时运行。我想确保现有数据没有丢失/损坏。
所有集成测试的例子我都遇到过几次运行Database.Migrate()
作为测试设置的一部分,然后播种,然后进行断言。但是,这仅在给定最新模式(已应用所有迁移)的情况下测试数据访问层时有用。它在测试特定迁移对已存在的数据的影响方面没有用。
题:
其他人如何解决跨迁移测试数据完整性的问题?我正在寻找一种适用于CI管道的设置。
请参阅我的其他答案,因为它更新,更简单,以下方法。
我能想到的一个选择,如下工作...... (请注意,我没有对此进行过测试,这只是现阶段的理论,所以请随时评论我可能出错的地方。我最后自己做了笔记,解决了我看到的问题;笔记对应于项目用*或^标记
假设您已经有IM,M1,M2,...,Mn的迁移,其中IM是初始迁移,迁移Mn是最后一次成功测试的迁移。现在让我们假设您要测试一个新的迁移Mn + 1,这是(除其他事项外)更新User
实体不再具有单独的FirstName
和LastName
属性的结果,而是具有单个Name
属性。我们给它命名为MergeFistAndLastNames
。
在继续测试方法之前,您必须完全捕获待测系统(SUT)的状态,之前应用迁移Mn + 1。因此请执行以下操作:
Before_MergeFistAndLastNames
编辑其后缀(例如)的名称。因此,需要更新实体User
,将其副本放在测试项目中并将其命名为User_Before_MergeFirstAndLastNames
。MembershipContext
,在测试项目中复制它并称之为MembershipContext_Before_MergeFirstAndLastNames
。现在为您的测试方法^^,您将:
IMigrator.Migrate
应用所有迁移,包括Mn。然后调用所需的服务来为测试数据库**播种。IMigrator.Migrate
,应用迁移Mn + 1。笔记:
*:如果将上下文复制到测试项目,则需要手动编辑其中与更新实体对应的任何DbSet
属性以使用复制的实体。例如,在上面的示例中,如果MembershipContext_Before_MergeFirstAndLastNames
具有属性DbSet<User> User {get; set;}
,则必须将其更改为DbSet<User_Before_MergeFirstAndLastNames> User {get; set;}
。
**:您可能需要拨打多个服务。如果你到处都在使用IoC,那么注入复制的服务应该相对容易。
***:数据完整性断言实际上取决于您正在测试的特定迁移及其潜在影响。对于上面给出的示例,可能值得检查使用(旧方法)单独的名字和姓氏播种的用户仍然可以通过更新的UserService
检索,该User
应返回Name
,User
等于串联名字和姓氏。
^:在测试新迁移时,需要清除迁移测试项目中的所有内容。
非正式证明:我们假设不需要这样做。使用上面的示例,该项目将包含一个测试方法,该方法引用对应于迁移Mn + 1的User
实体。现在让我们说对User
进行更新,这会导致更新的迁移Mn + 2。如果它以不再适用的方式引用Up
,则现有的测试方法可能不再编译。 ∎
上述技术在CI设置中可以很好地工作,其中所有先前的迁移在合并到生产之前已经过测试。在这样的设置中,只有对测试最新的迁移感兴趣才有意义。
^^:对于测试Down
迁移效果的每种测试方法,需要一种反向测试方法来测试相应的IMigrator.Migrate
迁移的影响。
这是一个比我描述的另一个更简单的方法。
安排:使用SqlCommand
将所有迁移应用到之前(包括)需要测试的迁移之前的迁移。然后是关键:使用qazxswpoi直接为数据库设定种子。
法案:应用需要测试的迁移。
断言。