Un enfoque que funciona es crear una clase de "inicializador de datos", agregarla a un contexto de aplicación Spring de prueba que también tenga su fuente de datos y conectar este contexto de aplicación en sus pruebas. Esto se basa en el hecho de que Spring almacena el contexto de la aplicación entre invocaciones de prueba.
Por ejemplo, una superclase de prueba:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:test-application-context.xml"})
@Transactional
public abstract class DataLoadingTest {
@Autowired
protected DatabaseInitialiser databaseInitialiser;
}
Con test-application-context.xml
:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" .../>
<bean class="DatabaseInitialiser">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
Y
public class DatabaseInitialiser extends JdbcDaoSupport {
@PostConstruct
public void load() {
// Initialise your database here: create schema, use DBUnit to load data, etc.
}
}
En este ejemplo:
- todas las pruebas que dependen de la base de datos extienden
DataLoadingTest
;
- Spring inicializa el contexto de la aplicación en la primera invocación de prueba;
- esto llama a
DatabaseInitialiser.load()
, a través de la anotación @PostConstruct
;
- Spring mantiene el contexto de la aplicación en un caché;
- invocaciones de prueba adicionales cableadas en el
DatabaseInitialiser
desde el contexto de la aplicación, que ya está en caché;
- Las pruebas son transaccionales y se retrotraen al final del conjunto de datos inicial.
Asimismo, DatabaseInitialiser
puede tener un método anotado @PostDestroy
para realizar cualquier rollback necesario, al final de toda la ejecución de prueba.
Esto es, de hecho, exactamente cómo resolví el problema, me olvidé de volver a poner mi código/respuesta en SO. Gracias por tomarse el tiempo para hacer esto para el próximo tipo. – HDave
Suena bien, pero en la práctica el '@PostConstruct' de la otra clase se ejecuta antes que el DatabaseInitialiser, por lo que no sirve de nada. Gracias por cualquier ayuda. –
@ united-expression: ¿puedes ampliar eso? ¿A qué otra clase te refieres? En el ejemplo que tengo, Spring inicializa el inicializador de la base de datos antes de la clase de prueba, que funciona en el Cass delineado en la pregunta. – Kkkev