在我的单元测试中,我自动安装了一些使用
等URL的DataSourcejdbc:derby:memory:mydb;create=true
创建内存中的数据库。
要删除内存Derby数据库,您必须连接:
jdbc:derby:memory:mydb;drop=true
我希望在每次测试后都能发生这种情况,并从一个新的数据库开始。我怎么能用Spring做到这一点?
答案 0 :(得分:5)
如果将Spring与Hibernate一起使用,有一种与数据库无关的方法。
确保在每个测试方法之前/之后创建/销毁应用程序上下文:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath*:application-context-test.xml"})
@TestExecutionListeners({DirtiesContextTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class})
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public abstract class AbstractTest {
}
指示Hibernate在启动时自动创建架构并在关闭时删除架构:
hibernate.hbm2ddl.auto = create-drop
现在每次测试之前
并在每次测试后
如果您正在使用交易,则可能需要添加TransactionalTestExecutionListener
。
答案 1 :(得分:4)
How to shutdown Derby in-memory database Properly
给了我一个解决方案的提示:
mydb.drop.url = jdbc:derby:memory:mydb;drop=true
...
<bean id="mydbDropUrl" class="java.lang.String">
<constructor-arg value="${mydb.drop.url}" />
</bean>
...
@Resource
private String mydbDropUrl;
@After
public void tearDown() {
try {
DriverManager.getConnection(mydbDropUrl);
} catch (SQLException e) {
// ignore
}
}
缺点是使用String构造函数接受String(围绕不可变String对象的不可变String对象)。我读到Spring 3中有一个@Value注释,这可能对此有所帮助,但我使用的是Spring 2.5。
如果您有更好的解决方案,请告诉我。
答案 2 :(得分:2)
在春季测试3之后,您可以使用注释来注入配置:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring-test.xml")
public class MyTest {
}
答案 3 :(得分:1)
如果您使用 spring-test.jar 库,则可以执行以下操作:
public class MyDataSourceSpringTest extends
AbstractTransactionalDataSourceSpringContextTests {
@Override
protected String[] getConfigLocations() {
return new String[]{"classpath:test-context.xml"};
}
@Override
protected void onSetUpInTransaction() throws Exception {
super.deleteFromTables(new String[]{"myTable"});
super.executeSqlScript("file:db/load_data.sql", true);
}
}
基于最新评论的更新版本,在每次测试之前删除db并重新创建表:
public class MyDataSourceSpringTest extends
AbstractTransactionalDataSourceSpringContextTests {
@Override
protected String[] getConfigLocations() {
return new String[]{"classpath:test-context.xml"};
}
@Override
protected void onSetUpInTransaction() throws Exception {
super.executeSqlScript("file:db/recreate_tables.sql", true);
}
}
答案 4 :(得分:1)
做一些像:
public class DatabaseTest implements ApplicationContextAware {
private ApplicationContext context;
private DataSource source;
public void setApplicationContext(ApplicationContext applicationContext) {
this.context = applicationContext;
}
@Before
public void before() {
source = (DataSource) dataSource.getBean("dataSource", DataSource.class);
}
@After
public void after() {
source = null;
}
}
让你的bean具有原型范围(scope="prototype"
)。这将在每次测试之前获得数据源的新实例。
答案 5 :(得分:0)
这是我们在每次测试开始时所做的事情。
删除所有以前的对象。
创建create_table.sql
根据您要测试的内容将值插入到创建的表中。
@Before
public void initialInMemoryDatabase() throws IOException, FileNotFoundException {
inMemoryDerbyDatabase.dropAllObjects();
inMemoryDerbyDatabase.executeSqlFile("/create_table_policy_version_manager.sql");
inMemoryDerbyDatabase.executeSqlFile("/insert_table_policy_version_manager.sql");
}
像魅力一样!