En primer lugar, encontré muchos hilos en StackOverflow sobre esto, pero ninguno de ellos realmente me ayudó, así que lamento hacer una pregunta posiblemente duplicada.
Estoy ejecutando pruebas JUnit usando spring-test, mi código se ve así
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {})
public class StudentSystemTest {
@Autowired
private StudentSystem studentSystem;
@Before
public void initTest() {
// set up the database, create basic structure for testing
}
@Test
public void test1() {
}
...
}
Mi problema es que quiero que mis pruebas NO influyan en otras pruebas. Así que me gustaría crear algo como una reversión para cada prueba. He buscado mucho esto, pero hasta ahora no he encontrado nada. Estoy usando Hibernate y MySql para esto
initTest
Respuestas:
Simplemente agregue una
@Transactional
anotación en la parte superior de su prueba:@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"testContext.xml"}) @Transactional public class StudentSystemTest {
Por defecto, Spring iniciará una nueva transacción en torno a su método de prueba y
@Before
/@After
callbacks, retrocediendo al final. Funciona por defecto, basta con tener algún administrador de transacciones en el contexto.De: 10.3.5.4 Gestión de transacciones (negrita mía):
fuente
PlatformTransactionManager
. De lo contrario, ¿cómo sabrá Spring sobre sus transacciones y su base de datos?@Transactional
a@Test
nivel de método y no a nivel de clase.Aparte: el intento de enmendar la respuesta de Tomasz Nurkiewicz fue rechazado:
Enlace correcto y permanente a la sección de documentación relevante sobre pruebas de integración.
fuente
Las respuestas que mencionan la adición
@Transactional
son correctas, pero para simplificar, podría tener su clase de pruebaextends AbstractTransactionalJUnit4SpringContextTests
.fuente
Lo sé, llegué demasiado tarde para publicar una respuesta, pero espero que pueda ayudar a alguien. Además, acabo de resolver este problema que tenía con mis pruebas. Esto es lo que tuve en mi prueba:
Mi clase de prueba
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "path-to-context" }) @Transactional public class MyIntegrationTest
Xml de contexto
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean>
Todavía tenía el problema de que la base de datos no se limpiaba automáticamente.
El problema se resolvió cuando agregué la siguiente propiedad a BasicDataSource
<property name="defaultAutoCommit" value="false" />
Espero eso ayude.
fuente
Debe ejecutar su prueba con un contexto Spring y un administrador de transacciones, por ejemplo,
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"/your-applicationContext.xml"}) @TransactionConfiguration(transactionManager="txMgr") public class StudentSystemTest { @Test public void testTransactionalService() { // test transactional service } @Test @Transactional public void testNonTransactionalService() { // test non-transactional service } }
Consulte el capítulo
3.5.8. Transaction Management
de la referencia de Spring para obtener más detalles.fuente
Además de agregar
@Transactional
un@Test
método, también debe agregar@Rollback(false)
fuente
Puede deshabilitar la reversión:
@TransactionConfiguration(defaultRollback = false)
Ejemplo:
@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @Transactional @TransactionConfiguration(defaultRollback = false) public class Test { @PersistenceContext private EntityManager em; @org.junit.Test public void menge() { PersistentObject object = new PersistentObject(); em.persist(object); em.flush(); } }
fuente