2012-07-03 47 views
19

我喜欢关于Rails'Django's测试方法的一件事是他们支持在每次测试运行之前使用灯具来建立数据库。使用灯具测试实体框架

在过去,我已经使用严格的单元测试与模拟存储库结合使用来测试我的代码,但是我很想拥有与上述测试方法一样易于使用的东西,以便执行集成测试。

我听说过这种类型的代码优先和EF 5的支持,但我不知道它是否升到了Rails和Django提供的水平。

当然有东西可比。 任何信息将不胜感激!

+0

我刚刚知道@LadislavMnrka将全部结束这一个。 :) –

+0

我相信[AutoFixture](https://github.com/AutoFixture/AutoFixture)与您正在寻找的解决方案相距甚远,但这是我能找到的用于EF自动化灯具的最接近的东西。 –

+0

不完全是,EF允许重新初始化数据库(再次创建它,可能添加数据等),但是这不附加到任何测试框架,当您在Visual Studio中重新启动应用程序时,每个事情都会完成。但是,如果需要,也可以从您的测试框架调用此初始化方法 –

回答

12

在EF5新概念已经推出,被称为迁移。您可能曾经在Rails或Django应用程序中使用过类似的东西。

迁移是一个类,它有几个功能来升级/降级数据库的版本。

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); 
    } 
} 

如果需要,可以将设置代码移动到基类。

+0

对于包含多个表和迁移历史记录较长的数据库,删除数据库并为每个测试类(甚至方法)重新创建它可能会给测试时间带来很大的开销。 –

6

我用Entity Framework开发了一个应用程序,它有600多个自动化集成测试。这是我使用的过程:

  • 实体框架代码第一次迁移只是为了设置数据库结构(表,索引等)。我不使用迁移来种子数据。

  • 用于将数据库设置为特定的已知状态的SQL脚本。例如,一个插入ASP.NET成员资格用户的脚本;另一个为最相关的表格设置样本数据;和其他更具体的场景。这些脚本通常会从适当的表中删除记录并再次插入,以避免关系冲突。这些脚本作为嵌入式资源包含在Visual Studio项目中。

  • 可以通过名称从资源中获取脚本并在数据库中执行脚本的助手类,包括使用“GO”命令批处理命令。 ConnectionContext.ExecuteNonQuery可用于此。

  • 在整个测试套件开始时,我执行设置用户,权限和其他非常常见的环境配置的脚本。

  • 每个测试方法之前,我执行一个或多个脚本,酌情设定在由测试正在运行所需的上下文数据库。例如,在读取,插入,更新和删除数据的一系列CRUD测试之前,我运行一个脚本,为测试数据分配适当的表。

  • 我写测试用例假设数据库在一个特定的上下文中设置。例如,更新操作的测试将尝试使用已知密钥检索记录,更新它并再次读取以检查它是否在数据库中更新。

虽然SQL脚本是不容易写,读为Rails的赛程,他们是非常快的,可以做任何需要的操作(如DELETE,INSERT,UPDATE,执行存储过程)。

该技术在涉及50个数据库表和非常复杂的业务规则和流程的一个项目是很好的证明。它保持测试简单和一致。

+0

感谢您的经验 – nXqd