我喜欢Rails'和Django's测试方法的一个原因是他们支持在每次测试运行之前使用fixture来设置数据库。
过去,我使用严格的单元测试和模拟的存储库来测试我的代码,但是我希望有一些像上述测试方法一样易于使用的东西,以便进行集成测试。
我听过一些关于代码优先和EF 5这种支持的讨论,但我不知道它是否达到了Rails和Django所提供的水平。
当然有可比的东西。 任何信息将不胜感激!
答案 0 :(得分:13)
在EF5中引入了新概念,称为迁移。您可能过去常常在Rails或Django应用程序中使用类似的东西。
迁移是一个类,它具有多个升级/降级DB版本的功能。
public partial class VoteTime : DbMigration
{
public override void Up()
{
AddColumn("Votes", "Time", c => c.DateTime(nullable:false, defaultValue:DateTime.UtcNow));
}
public override void Down()
{
DropColumn("Votes", "Time");
}
}
您还必须设置DbContext和DbMigrationsConfiguration配置类,以允许代码第一种方法工作。
出于测试目的,您需要介绍TestDatabaseInitilizer
public class TestDatabaseInitilizer : DropCreateDatabaseAlways<DbContext>
{
}
它将负责初始化测试数据库以进行单元测试。
最后,您应该设计测试代码来设置上下文。
public class SomeRepositoryTests
{
private DbContext _context;
[SetUp]
public void Setup()
{
Database.SetInitializer(new TestDatabaseInitilizer());
_context = new DbContext("TestContext");
_repository = new SomeRepository(_context);
}
[Test]
public void should_return_some_entities()
{
Assert.That(_repository.Get(), Is.Not.Null);
}
}
如果需要,可以将设置代码移动到基类。
答案 1 :(得分:6)
我开发了一个包含600多个自动集成测试的Entity Framework应用程序。这是我使用的过程:
实体框架代码首次迁移只是为了设置数据库结构(表,索引等)。我不使用迁移来播种数据。
将数据库设置为特定的已知状态的SQL脚本。例如,一个用于插入ASP.NET成员资格用户的脚本;另一个为最相关的表设置样本数据;和其他更具体的场景。脚本通常会从相应的表中删除记录,并以适当的顺序再次插入它们,以避免关系冲突。这些脚本作为嵌入式资源包含在Visual Studio项目中。
一个帮助程序类,它可以通过名称从资源获取脚本并对数据库执行,包括使用“GO”批处理命令。 ConnectionContext.ExecuteNonQuery可用于此。
在整个测试套件的开头,我执行设置用户,权限和其他非常一般环境配置的脚本。
在每个测试方法之前,我会根据需要执行一个或多个脚本,以便在运行的测试所需的上下文中设置数据库。例如,在读取,插入,更新和删除数据的一系列CRUD测试之前,我运行一个脚本,用适当的表为测试数据添加种子。
我假设数据库是在特定的上下文中设置的,我会编写测试用例。例如,对更新操作的测试将尝试检索具有已知密钥的记录,更新它并再次读取以检查它是否在数据库中更新。
尽管SQL脚本不像Rails夹具那样容易编写和读取,但它们非常快并且可以进行任何需要的操作(例如DELETE,INSERT,UPDATE,执行存储过程)。
这项技术在涉及50个数据库表和非常复杂的业务规则和流程的项目中得到了充分证明。它使测试简单而一致。