我试图写单元/集成测试我的ASP.NET Web API项目,并奋力奔跑在隔离每个测试。 请允许我解释一下。
我有一个* .testsettings与配置部署设置文件。 每个测试运行之前,一个空的* .mdf文件部署到测试位置。 由于我使用的实体框架代码首先,我可以使用数据库初始化到我的模式推到数据库和种子特定表2行。 这个伟大的工程。
我现在面临的问题是,我所有的ApiControllers'行动的各种测试踩到对方的脚,如果他们在错误的顺序执行。 例如,如果我的POST测试之前运行GET测试然后GET返回2个对象与如果它们以相反的顺序执行,然后返回GET 3级的对象。
我想,我需要做的是下降,重现和每次测试之前补种我的数据库。 这是一个好主意,或者有更好的办法吗? 如果这是我能做的最好,我想我去每个测试之前重置我的数据库。
下面是我落得这样做对任何人有兴趣。
我扩展DropCreateDatabaseAlways<TContext>
和推翻了种子的方法来填充我的数据库与我的单元测试可以依靠已知的测试数据。
public class MyDatabaseInitializer : System.Data.Entity.DropCreateDatabaseAlways<MyDbContext>
{
protected override void Seed(MyDbContext context)
{
// Add entities to database.
context.SaveChanges();
}
}
然后我实现的[AssemblyInitialize]
方法,其设置数据库初始化。
[TestClass]
public class Global
{
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext context)
{
System.Data.Entity.Database.SetInitializer(new MyDatabaseInitializer());
}
}
这将设置初始化数据库,但实际上并没有运行。 该intitializer是在运行[TestInitialize]
方法,我写这迫使数据库每次测试前被丢弃,重建和重新播种。
[TestClass]
public class MyTestClass
{
[TestInitialize]
public void TestInitialize()
{
MyDbContext context = new MyDbContext();
context.Database.Initialize(true);
}
[TestMethod]
public void MyUnitTest()
{
Assert.IsTrue(true);
}
}
我建议重新创建数据库在你开始测试,然后包裹在每一个总是回滚事务之前。 这是非常有益的,如果你重新创建阶段,需要大量的时间来完成(例如,由于需要执行等的行动)。
在我们当前的设置,我们要重新建立数据库架构加载之前每类(ClassInitialize属性,但是这肯定可以被移动到AssemblyInitialize),只是播种/清洗前用适当的记录的数据库/每个测试运行后(与TestInitialize / TestCleanup属性)。
更多信息: http://msdn.microsoft.com/en-us/library/ms379625(v=vs.80).aspx