Nig*_*888 8 continuous-integration unit-testing entity-framework database-migration ef-migrations
我正在使用与TeamCity,NUnit和Git的持续集成.我最近从FluentMigrator迁移(赦免双关语)到实体框架迁移.我主要是为了利用其中的脚手架功能.
但是,有可能检查源控件的某些更改,而无需先将更改支持迁移(假设在提交和推送提交之前未运行应用程序的方案).我正在使用预先测试的提交工作流程,所以我想在预测试中检测到这个问题,而不是等到调用migrate.exe(这在我的工作流程中为时已晚并打破"绿色存储库").
我的问题是,如何创建单元/集成测试来检测迁移模型何时与上下文模型不匹配,以便在尝试迁移之前我可以使构建失败?请注意,我希望它不匹配数据库,并且不希望从测试中访问数据库.
我试过这种方法:
[Test]
public void CheckWhetherEntityFrameworkMigrationsContextIsUpToDate()
{
Assert.DoesNotThrow(() =>
{
CallDatabase();
});
}
private void CallDatabase()
{
using (var ctx = new MyContext("SERVER=(local);DATABASE=MyDatabase;Integrated Security=True;"))
{
var tenant = (from t in ctx.Tenant
select t).FirstOrDefault();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当存在挂起的迁移时,这总是会失败(而不仅仅是在迁移模型与上下文模型不同步的情况下,这就是我所追求的).
我已在EntityFramework项目中为此问题添加了一个工作项.希望他们会考虑添加一种方法来实现这一目标.
Pab*_*meo 11
如果有人发现这个有用,我会使用以下代码通过针对测试数据库运行所有迁移来测试迁移:
[TestClass]
public class MigrationsTests
{
[TestMethod]
public void RunAll()
{
var configuration = new Configuration();
var migrator = new DbMigrator(configuration);
// back to 0
migrator.Update("0");
// up to current
migrator.Update();
// back to 0
migrator.Update("0");
}
}
Run Code Online (Sandbox Code Playgroud)
这将测试所有Up和Down迁移,以及在关闭自动迁移时检测挂起的更改.
注意:确保对测试数据库运行此操作.在我的例子中,测试项目app.config具有到测试数据库的connectionString(只是一个本地SQLExpress实例).
这是一些代码,将检查所有模型更改是否都已被移植到迁移中。
bool HasPendingModelChanges()
{
// NOTE: Using MigratorScriptingDecorator so changes won't be made to the database
var migrationsConfiguration = new Migrations.Configuration();
var migrator = new DbMigrator(migrationsConfiguration);
var scriptingMigrator = new MigratorScriptingDecorator(migrator);
try
{
// NOTE: Using InitialDatabase so history won't be read from the database
scriptingMigrator.ScriptUpdate(DbMigrator.InitialDatabase, null);
}
catch (AutomaticMigrationsDisabledException)
{
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我想要这里给出的所有答案中最好的,所以这是我想出的:
[TestClass()]
public class MigrationsTests
{
[TestMethod()]
public void MigrationsUpDownTest()
{
// Unit tests don't have a DataDirectory by default to store DB in
AppDomain.CurrentDomain.SetData("DataDirectory", System.IO.Directory.GetCurrentDirectory());
// Drop and recreate database
BoxContext db = new BoxContext();
db.Database.Delete();
var configuration = new Migrations.Configuration();
var migrator = new DbMigrator(configuration);
// Retrieve migrations
List<string> migrations = new List<string>;
migrations.AddRange(migrator.GetLocalMigrations());
try
{
for (int index = 0; index < migrations.Count; index++)
{
migrator.Update(migrations[index]);
if (index > 0) {
migrator.Update(migrations[index - 1]);
} else {
migrator.Update("0"); //special case to revert initial migration
}
}
migrator.Update(migrations.Last());
}
catch (SqlException ex)
{
Assert.Fail("Should not have any errors when running migrations up and down: " + ex.Errors[0].Message.ToString());
}
// Optional: delete database
db.Database.Delete();
}
[TestMethod()]
public void PendingModelChangesTest()
{
// NOTE: Using MigratorScriptingDecorator so changes won't be made to the database
var migrationsConfiguration = new Migrations.Configuration();
var migrator = new DbMigrator(migrationsConfiguration);
var scriptingMigrator = new MigratorScriptingDecorator(migrator);
try
{
// NOTE: Using InitialDatabase so history won't be read from the database
scriptingMigrator.ScriptUpdate(DbMigrator.InitialDatabase, null);
}
catch (AutomaticMigrationsDisabledException)
{
Assert.Fail("Should be no pending model changes/migrations should cover all model changes.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
值得注意的几件事:
[assembly: InternalsVisibleTo("MyTestsProject")]到Configuration班级的顶部App.config仅用于测试项目的实体框架连接字符串,因为数据库将被频繁删除和重新创建 - 如果在构建机器上运行请记住并行运行可能会导致冲突,因此您可能需要更改每个构建的字符串| 归档时间: |
|
| 查看次数: |
4370 次 |
| 最近记录: |