Estou fazendo uns testes integrados com HSQLDB em memória, utilizando spring.
No meu teste eu coloco, além da anotação @Test, @Rollback ou @Rollback(true), mas oq é inserido no banco não está sendo apagado.
Eu fiz um teste:
@Test @Transactional @Rollback
public void testSalvaUsuario(){…}
Dessa forma funcionou.
Mas o @Rollback não deveria funcionar sem outra anotação ?
Alguem sabe me explicar oq acontece ?
Você precise usar a seguinte anotação para os testes de integração com o Spring: @RunWith(SpringJUnit4ClassRunner.class). @ContextConfiguration({ “/test-datasource-context.xml”})
test-datasource-context.xml : aqui ficaria suas configurações do HSQLDB.
Com isso o Spring se encarrega do trabalho de rollback assim como aproveitar a carga do contexto para os
proximos testes.
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({“classpath:/testApplicationContext.xml”}) @ActiveProfiles(“test”)
public abstract class AbstractControllerTest {
}
public class AppControllerTest extends AbstractControllerTest
É o seguinte, quando o Spring carrega o contexto de testes ele o faz uma unica vez e pelo que estou vendo a carga no banco se dá uma unica vez. Desta forma você terá que informar ao spring explicitamente que você não deseja comitar. Você já esta fazendo com o @Rollback, outra forma de fazer isso seria usar os metodos do
cliclo de vida do seu framework de teste para fazer a carga dos dados a cada teste, porem isso iria impactar no desempenho.
Você pode adicionar a sua AbstractControllerTest a anotação @TransactionConfiguration(defaultRollback = true) ou manter a configuração que você já vem usando visto que esta funcionando.
Não sei se respondi a sua pergunta mas foi isso que entendi!
O @Transactional é uma anotação que diz ao Spring quando iniciar a transação, quando você coloca ela na classe vc diz que a partir de qualquer metodo chamado
na classe mencionada será iniciada uma trasação, portanto quando se chama o DAO/Servico a partir desta classe com o @Transactional o proxy do spring identificará que já existe uma trasação aberta e irá usar essa transação no DAO/Servico que foi chamado, isso se chama Propagação transacional, dependendo da configuração irá herdar a transação ou criará uma nova, tudo vai depender do perfil trasacional.
Voltando a história do @Trasactional, se vc não adicionar isso na sua classe de teste o proxy do spring ao receber a chamada do seu teste ao DAO/Service irá identificar que não existe uma trasação corrente, então ele criará uma nova e quando o metodo do seu DAO ou Serviço retornar o Spring irá fechar a transação, ou seja, você já não poderá usar o lazy do hibernate porque essa transação já foi fechada.
Nos testes de exemplo do Spring ele usa o @Trasactional na classe e usa o @RollBack(true) no metodo, pois entende-se que nos outro metodos ele quer que seja feito o commit, quando colocado @Rollback na classe endende-se que será realizado rollback para todos os metodos da classe anotada, capti?
Então…
Eu fiz o seguinte nos meus métodos, no service.
@Transactional
public void atualizaUsuario(Usuario usuario) {
entityManager.merge(usuario);
}
Mas não testei com @Transactional direto na classe, como vc disse…
Vou testar e posto aqui.
Vlw a ajuda !
Edit:
Testei aqui.
Ééé… não funcionou com @Transactional direto na classe
Bem… deixa rolar…
Edit 2:
Qd vc disse q o spring coloca @Transactional na classe, eu pensei errado e coloquei na classe service ao invés de colocar na classe de test.
Colocando na classe de test funciona sim