是否有人知道如何实现以下用于测试DAO的流程:
使用Spring,Hibernate,JUnit,Maven堆栈。
据我所知,最佳实践是我们为每个测试DAO(@BeforeClass)创建数据,并在完成所有测试后(@AfterClass)清理相同的数据。
但是在我们的例子中,不同数据库表之间存在太多依赖关系(客户端的遗留数据库:(目前无法做任何事情)。用测试数据填充每个表需要许多其他表中的数据因此,为每个DAO单独创建数据将非常困难且耗时。因此,我们确实只需要创建一次DB测试数据。
我使用BaseDAO中的静态块创建了测试数据(由每个DAO测试类扩展) - 显然只运行一次。但是当所有测试(所有DAO测试子类)完成时,如何清理相同的问题。在DAO Test类完成后,每次都会运行基类中的@AfterClass拆解方法。
请告知。
答案 0 :(得分:3)
如果你正在使用Maven,一个不错的选择是使用DBUnit。它允许您从数据库导出测试数据(或只是用XML编写),以便为测试导入。它有Maven plugin,可以满足您的需求。
答案 1 :(得分: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:
@Service
public class DbCleanup {
@Resource
private DataSource ds;
@PreDestroy
public cleanUpDb() {
//do your cleanup with DB
}
}
答案 2 :(得分:1)
我使用以下解决方案。
(1)我有一个名为Fixture的简单界面
package com.obecto.fixtures;
public interface Fixture {
void prepare();
}
(2)我准备一个SQL fixture来填充一个空数据库 - 这可以通过实体或像这样执行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)将您的灯具注入Test类,prepare
- 将它们注入@Before
- 方法。
始终使用其他数据库进行测试,因此您可以安全地使用hibernate的 create-drop 设置。要在每个测试方法之前重新加载上下文,您可以使用以下注释 - @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD)
答案 3 :(得分:1)
没有人建议为每个测试使用@Transactional属性进行注释。如果db引擎支持它,那应该负责回滚状态。有关详情,请参阅here或stackoverflow link。
答案 4 :(得分:0)
通常我备份整个数据库实例(实际上我正在使用Oracle和imp / exp是很棒的工具)。 SQL Server和相似的都有复制方法。准备好数据后,只需导出整个实例并在测试前加载它。
测试完成后,删除数据库并重新创建。 (使用本机程序转储和加载整个数据库可能比预期的更快)
此致
PS:如果可以,只需在虚拟机上构建克隆数据库,然后在虚拟机中保存快照(以便稍后恢复)。
答案 5 :(得分:0)
您还可以使用数据库模型工具,例如Acolyte(https://github.com/cchantep/acolyte),在这种情况下,您无需清理数据,确保哪些数据可用于哪个JDBC进行哪些测试,而无需更改JDBC基于您想要测试的代码。
注意:我是Acolyte的作者。