2011-09-27 66 views
4

有谁知道的方式来实现测试DAO的流程如下:创建和清洁DB设置一次测试所有的DAO

  • 运行SQL脚本来创建公共DB设定(将数据插入到所有表)
  • 测试DAO1
  • 测试DAO2
  • ...
  • 清理DB数据步骤创建1

使用Spring,Hibernate,JUnit,Maven堆栈。

我明白,最好的做法是,我们为每个测试DAO(@BeforeClass)和清理相同的数据所有测试完成后(@AfterClass)之后。

但是在我们的例子中,不同数据库表之间的依赖关系太多了(客户端的遗留数据库:-(目前无法做到这一点)。用测试数据填充每个表需要将其他许多表中的数据作为那么,为每个DAO单独创建数据将是非常困难且耗时的,因此,我们确实需要创建DB测试数据只需要一次

我已经使用BaseDAO中的静态块创建了测试数据DAO Test Class) - 它显然只运行一次,但是当所有DAO Test子类中的所有测试都完成时,如何进行相同的清理问题在基类中的@AfterClass拆卸方法每次都会在DAO Test类之后运行完成。

请指教。

回答

3

,一个很好的选择是使用DBUnit。它允许您从数据库中导出测试数据(或者只是将其写入XML),以便导入您的测试。它有一个Maven plugin这将做你所需要的。

+0

不知道是否maven是要走的路。有时你需要在执行每个测试方法之前准备数据库。是否有可能通过Maven实现这一点? –

+0

好的,你说得对。问题的细节是只准备一次。 –

+1

是的。我们用JUnit'@ MethodRule'(或JUnit 4.9中的'@ TestRule')来完成它,它在每个测试方法之前设置数据库,并在之后进行清理。无论哪种方式,OP已经在使用Maven,并且要求数据库设置环绕整个测试阶段,而不是测试方法,如问题所述。 – Daniel

0

我一般备份整个数据库实例(其实我与甲骨文合作和小鬼/ EXP是伟大的工具)。 SQL Server和其他人有复制方法。准备好数据后,只需导出整个实例并在测试之前加载它。

一旦测试完成后,删除DB和重建。 (反倾销和加载整个DB与本机程序可以快于预期)

问候

PS:如果你可以,只是建立了一个克隆数据库的虚拟机上,然后保存快照OV虚拟机(所以你可以稍后恢复它)。

1

在春季3:

<jdbc:embedded-database id="dataSource"> 
    <jdbc:script location="classpath:schema.sql"/> 
    <jdbc:script location="classpath:test-data.sql"/> 
</jdbc:embedded-database> 

Documentation。要清理测试后的数据库中,创建一个Spring bean,将只在测试过程中被拾起:如果您使用的Maven

@Service 
public class DbCleanup { 
    @Resource 
    private DataSource ds; 

    @PreDestroy 
    public cleanUpDb() { 
     //do your cleanup with DB 
    } 
} 
1

我采用如下方案。

(1)I有一个称为夹具

package com.obecto.fixtures; 

public interface Fixture { 

    void prepare(); 

} 

(2)I制备SQL夹具来填充空数据库简单的界面 - 这可以通过实体或通过执行这样的SQL来完成:

package com.avaco2.fixtures; 

import java.util.logging.Logger; 

import org.apache.commons.dbcp.BasicDataSource; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.core.io.ClassPathResource; 
import org.springframework.core.io.Resource; 
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; 
import org.springframework.stereotype.Component; 
import org.springframework.test.jdbc.SimpleJdbcTestUtils; 

import com.obecto.fixtures.Fixture; 

@Component(value="logEventsSQLFixture") 
public class LogEventsSQLFixture implements Fixture { 
    private static String IMPORT_SQL = "import-LogEvents.sql"; 
    private static Logger LOG = Logger.getLogger(LogEventsSQLFixture.class.getName()); 

    @Autowired 
    private BasicDataSource dataSource; 

    @Override 
    public void prepare() { 
     SimpleJdbcTemplate jdbcTemplate = new SimpleJdbcTemplate(dataSource); 
     Resource sqlScript = new ClassPathResource(IMPORT_SQL); 
     try { 
      SimpleJdbcTestUtils.executeSqlScript(jdbcTemplate, sqlScript, true); 
     } catch (Exception e) { 
      LOG.severe("Cannot import " + IMPORT_SQL); 
     } 

    } 

} 

(3)注入你的灯具到测试类和prepare -them在@Before - 方法。

总是使用另一个数据库进行测试,因此您可以安全地使用创建 - 删除设置休眠。要重新加载各测试方法之前,你可以使用下面的注释上下文 - @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)

1

没有人建议用每个测试@事务属性注释。如果数据库引擎支持它,应该注意回滚状态。有关详细信息,请参见herestackoverflow link

0

您还可以使用数据库模型工具,如Acolyte(https://github.com/cchantep/acolyte),在这种情况下,您不需要清理数据,确定哪些数据可用于哪些JDBC进行哪些测试,而无需更改基于JDBC的代码想要测试。