Boa tarde!
Implementei um método de teste usando TestNG com a intenção de capturar uma exceção que seria gerada ao tentar remover um registro de uma tabela que é referenciada por outra tabela. Nesse caso ocorreria uma tentativa de violação de constraint. Ao executar o código percebo no log de erro do TestNG que é gerada a exceção org.hibernate.exception.ConstraintViolationException, entretanto ao tentar capturá-la não consegui. Fazendo alguns testes percebi que a exceção que de fato é gerada é outra, javax.persistence.PersistenceException (ou alguma filha mais específica, que não descobri). Percebi que o valor “org.hibernate.exception.ConstraintViolationException” aparece como texto do método getMessage (da exceção capturada PersistenceException).
Fiz várias pesquisas e percebi que existe dificuldade com esse tipo de exceção há um bom tempo, mas não encontrei uma solução ou explicação legal.
Obs: Estou usando JPA com Hibernate.
Abaixo está o código que implementei "tentando" contornar esse problema:
@Test(dependsOnMethods = { "adicionaUnidadesAUmCursoExistente" },
expectedExceptions = { ViolacaoDeConstraintException.class })
public void tentaRemoverUmCursoComUnidadesMasNaoConsegue() {
Curso curso = cursoDAO.busca(cursoId);
try {
cursoDAO.remove(curso);
em.flush(); // para que as constraints sejam validadas
} catch (PersistenceException e) {
/*
* não é possível capturar ConstraintViolationException. Ela consta
* como resultado (texto) do e.getMessage().
*/
if (e.getMessage().contains("ConstraintViolationException")) {
throw new ViolacaoDeConstraintException(e.getMessage());
} else {
throw e;
}
}
}
O Try/Catch não seria necessário, caso fosse possível capturar a exceção correta.
A tentativa inicial foi por capturar ConstraintViolationException, mas isso me cheirou mal pelo fato de que essa é uma exceção do Hibernate e não da JPA. E a ideia seria não vincular o código a recursos específicos de um privider ORM. Mas como essa foi a exceção apresentada, comecei por ela. Depois percebi que a exceção lançada é da JPA, e não é mostrada no log. Descobri fazendo testes.
Imagino que o melhor mesmo seria trabalhar com exceções da JPA, mas analisando o javadoc não descobri uma exceção mais específica que PersistenceException (equivalente à ConstraintViolationException do Hibernate). Eexiste?
Imagino que o melhor seria um código semelhante ao que segue:
@Test(dependsOnMethods = { "adicionaUnidadesAUmCursoExistente" },
expectedExceptions = { NomeDaExcecaoEspecificaDaViolacaoDeConstraintDoJPA.class })
public void tentaRemoverUmCursoComUnidadesMasNaoConsegue() {
Curso curso = cursoDAO.busca(cursoId);
cursoDAO.remove(curso);
em.flush(); // para que as constraints sejam validadas
}
Estou aprendendo a trabalhar com testes nesse projeto acadêmico. Talvez esse tipo de teste não seja um "teste de valor" (testar constraints?), mas como sou iniciante acho que ta valendo. Preciso praticar e aprender como as coisas funcionam.
Coisarada...
Alguém poderia me ajudar a esclarecer essas questões?
Desde já agradeço.