java - transaction - ¿Cómo revertir una transacción de base de datos cuando se prueban servicios con Spring en JUnit?
spring transaction propagation (4)
Necesita extender los límites de las transacciones a los límites de su método de prueba. Puede hacerlo anotando su método de prueba (o toda la clase de prueba) como @Transactional
:
@Test
@Transactional
public void testInsert(){
long id=myService.addPerson("JUNIT");
assertNotNull(id);
if(id<1){
fail();
}
}
También puede usar este enfoque para asegurarse de que los datos se escribieron correctamente antes de la reversión:
@Autowired SessionFactory sf;
@Test
@Transactional
public void testInsert(){
myService.addPerson("JUNIT");
sf.getCurrentSession().flush();
sf.getCurrentSession().doWork( ... check database state ... );
}
No tengo problemas para probar mi DAO y mis servicios, pero cuando pruebo INSERT
s o UPDATE
s quiero deshacer la transacción y no afectar mi base de datos.
Estoy usando @Transactional
dentro de mis servicios para administrar transacciones. Quiero saber si es posible saber si una transacción estará bien, pero si la revierte para evitar la alteración de la base de datos.
Esta es mi prueba:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/META-INF/spring.cfg.xml")
@TransactionConfiguration(defaultRollback=true)
public class MyServiceTest extends AbstractJUnit38SpringContextTests {
@Autowired
private MyService myService;
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Test
public void testInsert(){
long id = myService.addPerson( "JUNIT" );
assertNotNull( id );
if( id < 1 ){
fail();
}
}
}
El problema es que esta prueba fallará porque la transacción se canceló, ¡pero la inserción está bien! Si @TransactionConfiguration(defaultRollback=true)
entonces el pase de prueba pero se insertará un nuevo registro en la base de datos.
@Test
@Transactional
@Rollback(true)
public void testInsert(){
long id = myService.addPerson( "JUNIT" );
assertNotNull(id);
if( id < 1 ){
fail();
}
}
Ahora puede pasar la prueba correctamente, pero la reversión se ignora y el registro se inserta en la base de datos. He anotado el método addPerson()
dentro de myService con @Transactional
, obviamente. ¿Por qué se ignora la reversión?
Si tu
myService.addPerson("JUNIT");
El método está anotado como @Transactional. Obtendrá algunos tipos o errores diferentes al intentar arreglar esto. Así que mejor prueba los métodos DAO.
Use la siguiente anotación antes de la clase:
@TransactionConfiguration(transactionManager = "txManager",defaultRollback = true)
@Transactional
aquí txManager
es el Administrador de transacciones del contexto de la aplicación.
Aquí txManager
es una instancia o id de bean del administrador de transacciones desde el application context
.
<!-- Transaction Manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
Agregue su código dentro del método setUp()
, esto se ejecutará al inicio de la prueba y el último código de recapitulación se debe poner en el método teatDown()
que finalmente se ejecutará. o también puede usar @Before
y @Before
annotation en lugar de hacerlo.
revisa
http://static.springsource.org/spring/docs/2.5.x/reference/testing.html
Sección 8.3.4 en particular
Spring tiene algunas clases de prueba que ajustarán cada prueba en una transacción, por lo que la base de datos no se cambia. Puede cambiar esa funcionalidad si lo desea también.
Editar: en función de sus más información, es posible que desee ver
AbstractTransactionalJUnit38SpringContextTests at