测试实体框架核心迁移

时间:2019-09-25 14:41:17

标签: c# unit-testing entity-framework-core mstest

您如何使用单元/集成测试来确保代码优先迁移在已填充的上一版本数据库上正常工作,包括将数据从一个列或表映射到另一列或表的任何其他代码?

我在System.Data.Entity命名空间中找到了使用类的以前的答案,但是看来这些问题在Entity Framework Core中已经过时了,并且无法手动控制迁移吗?

我为自己找到了一个解决方案,可以发布,但是我欢迎其他更好的解决方案。

1 个答案:

答案 0 :(得分:0)

数据库由Context类和ContextModelSnapshot类,一系列迁移文件以及数据表存储的C#对象定义。

如果尚未创建迁移,请将所有这些文件复制到测试项目中,并使用后缀将所有类重命名,例如“ MyDataEntity” =>“ MyDataEntityVersion1”。相应地编辑捆绑的.Design.cs文件。然后,在原始文件上创建新的迁移。

如果创建了新迁移,但不能后退,则可以手动编辑ContextModelSnapshot文件以还原更改。

这项工作的关键是两个都指向同一个数据库文件。一个期望原始状态,另一个期望升级状态。

在测试用例中,您可以执行以下操作:

[TestInitialize]
public void TestInit()
{
    using (var db = new MyDataContext())
        db.Database.EnsureDeleted(); // reset database before each test
}

[TestMethod]
public void Migrate_Version1_To_Version2_On_Populated_Database()
{
    using (var db = new MyDataContextVersion1())
        db.Database.Migrate(); // create database and apply migrations up through Version 1

    // populate the Version 1 database

    App.InitializeDatabase(); // whatever method you would normally call to read/update the database

    // assert statements to test that the Version 2 database looks like you expect.
}

InitializeDatabase()类似于:

public void InitializeDatabase()
{
    using (var db = new MyDataContext())
    {
        db.Database.Migrate();

        // detect if upgrade needed and set new columns

        db.SaveChanges(); 
    }
}

请注意,此解决方案部分是通过使用SQLite来实现的,SQLite不支持在迁移中删除列。这使我不愿尝试在迁移过程中做更多的幻想。