JUnit + + Derby de primavera: caída db en memoria después de cada prueba
-
12-10-2019 - |
Pregunta
En mis pruebas de unidad que autowired algunos DataSources, que utilizan URLs como
jdbc:derby:memory:mydb;create=true
Para crear un DB en memoria.
Para soltar un Derby en memoria db tiene que conectar con:
jdbc:derby:memory:mydb;drop=true
Me gustaría que esto suceda después de cada prueba y comenzar con una base de datos nueva. ¿Cómo puedo hacer esto utilizando Spring?
Solución 2
Cómo apagado Derby base de datos en la memoria correctamente
Me dio un toque a una solución:
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
}
}
Una desventaja es el uso del constructor de cadena que acepta una cadena (una cadena objeto inmutable alrededor de un objeto Cadena inmutable). He leído que hay una anotación @Valor en la primavera de 3, lo que podría ayudar aquí, pero estoy utilizando Spring 2.5.
Por favor, hágamelo saber si usted tiene una solución mejor.
Otros consejos
Hay una forma de base de datos independiente del de hacer esto si está utilizando la primavera junto con Hibernate.
Asegúrese de que se creará el contexto de aplicación / destruida antes / después de cada método de prueba:
@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 {
}
Instruir Hibernate para crear automáticamente el esquema en el arranque y para descartar el esquema en el apagado:
hibernate.hbm2ddl.auto = create-drop
Ahora, antes de cada prueba
- el contexto de aplicación se crea y se inyectan los granos de resorte requeridos (primavera)
- las estructuras de bases de datos se crean (hibernación)
- se ejecuta el import.sql si está presente (hibernación)
y después de cada prueba
- el contexto de aplicación se destruye (primavera)
- el esquema de base de datos se deja caer (hibernación).
Si está utilizando transacciones, es posible que desee añadir el TransactionalTestExecutionListener
.
Después de pruebas de la primavera 3, puede utilizar las anotaciones para inyectar configuraciones:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring-test.xml")
public class MyTest {
}
Sólo hacer algo como:
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;
}
}
Haga su frijol tiene un alcance de prototipo (scope="prototype"
). Esto hará que una nueva instancia de la fuente de datos antes de cada prueba.
Si se utiliza el primavera-test.jar biblioteca, puede hacer algo como esto:
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);
}
}
Y una versión actualizada en base al último comentario, que cae tablas db y vuelve a crear antes de cada prueba:
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);
}
}
Esto es lo que hacemos al comienzo de cada prueba.
-
Descartar todos los objetos anteriores.
-
Crea todas las tablas mencionadas en el create_table.sql
-
Los valores se insertan en las tablas creadas en base a lo que quiere prueba.
@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"); }
funciona como un encanto!