Br.com.caelum.vraptor.util.test.HibernateMockValidator VRaptor 3.3.0

24 respostas
A

Lucas,

Baixei a nova versão do VRaptor porém a classe acima (a que eu tinha sugerido) não funcionou. Não gerou erro nem log. Simplesmente os testes não passaram

@Test
    public void AdicionarNovoCadastro(){
       CadastroGeral cad = new CadastroGeral("teste nome", "[telefone removido]");
       controller.salva(cad);
       assertTrue(dao.existeCadastroPorCpfCnpj("[telefone removido]"));
    }

    @Test(expected=ValidationException.class)
    public void AdicionaComNomeNulo(){
       CadastroGeral cad = new CadastroGeral( );
       cad.setCpfcnpj("[telefone removido]");
       controller.salva(cad);
    }

ambos os testes deveriam passar no junit, mas nenhum deu…
vi que as classes que foram usadas na implementação usam as classes diretas do hibernate e por isso não consegui identificar o que está havendo de errado.

se vc tiver tempo, tenta testar ai.

abs.

24 Respostas

G

Oi Wagner. Não sou o Lucas, mas quem sabe eu possa ajudar. Fui eu quem implementou a integração com o Bean Validator.

Essa sua classe na verdade faz o que? Ela é um mock para fazer de conta que é o Hibernate Validator 3x ou 4x?

Essa sua DAO está sendo criada como? Ela é um mock ou classe concreta? Como você injeta o Entity Manager nela?

Lucas_Cavalcanti

o cad passa no hibernate validator?

seu controller tem a chamada ao validator.onErrorXXXX?

Lucas_Cavalcanti

BTW eu removi os logs da implementação

A

Lucas, creio que o problema é que a implementação que o garcia fez usa as classes base do hibernate, e portanto ela não dispara o erro , mas é só uma opinião.

garcia-jj:
Oi Wagner. Não sou o Lucas, mas quem sabe eu possa ajudar. Fui eu quem implementou a integração com o Bean Validator.

Essa sua classe na verdade faz o que? Ela é um mock para fazer de conta que é o Hibernate Validator 3x ou 4x?

Essa sua DAO está sendo criada como? Ela é um mock ou classe concreta? Como você injeta o Entity Manager nela?

  1. é Um mock para fazer de conta que é o Hibernate Validator, pois o MockValidator normal não implementava o .validate(objeto)
  2. Uso um Dao concreto, pois AINDA não sei usar o Mockito ( um passo de cada vez, rsrsrsrsr)

veja neste link o codigo que eu tinha sugerido, baseado na implementacao do leandros … http://www.guj.com.br/java/231575-resolvido-github--vraptor---ajuda-para-fazer-um-mini-tutorial#1191480

Lucas Cavalcanti:
o cad passa no hibernate validator?

seu controller tem a chamada ao validator.onErrorXXXX?

  1. sim. o cadastro passa no validator. (o que tem que passar, e o que gera erro, dããã, está gerando o erro) isto, executando/subindo a classe/projeto e fazendo os testes na mão
  2. o controller tem a chamada ao validator.onError

para aprendizes como eu que os logs são uteis, mesmo que do tipo debug

========================

Controller

public void salva(final CadastroGeral cadastro) {
      validator.validate(cadastro);

      validator.onErrorUsePageOf(this).formulario();
      this.dao.save(cadastro);
      //result.include("alerta", "Cadastro '" + cadastro.getNome() + "' adicionado com sucesso.");
      result.redirectTo(this).lista();
   }

Dao que extende um dao generico

package br.com.admwagner.processos.dao;

import br.com.admwagner.processos.model.CadastroGeral;
import br.com.caelum.vraptor.ioc.Component;
import org.hibernate.Query;
import org.hibernate.Session;

@Component
public class CadastroGeralDao extends DaoGenericoHibernate<CadastroGeral, String> {

   public CadastroGeralDao( Session session) {
      super.setSession(session);
   }

   public boolean existeCadastroPorCpfCnpj(String cpfcnpj) {
		String hql = "from CadastroGeral cad where cad.cpfcnpj = :cpfcnpj";
		Query query = super.getSession().createQuery(hql).setParameter("cpfcnpj", cpfcnpj);

		return !query.list().isEmpty();
   }

   public CadastroGeral buscaCadastroPorCpfCnpj(String cpfcnpj) {
		String hql = "from CadastroGeral cad where cad.cpfcnpj = :cpfcnpj";
		Query query = super.getSession().createQuery(hql).setParameter("cpfcnpj", cpfcnpj);

		return (CadastroGeral) query.uniqueResult();
   }


}

teste junit

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.admwagner.processos.controller;




import java.util.List;
import org.apache.log4j.Logger;

import br.com.admwagner.util.HibernateMockValidator;                - ESTA É A CLASSE QUE EU IMPLEMENTEI

//import br.com.caelum.vraptor.util.test.HibernateMockValidator;    -  ESTA É A CLASSE QUE ESTA NO VRAPTOR 
import br.com.caelum.vraptor.util.test.MockResult;
import br.com.admwagner.processos.dao.CadastroGeralDao;
import br.com.admwagner.processos.model.CadastroGeral;
import br.com.admwagner.util.CriadorSession;



import br.com.caelum.vraptor.validator.ValidationException;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.hibernate.classic.Session;

import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;


public class CadastroGeralControllerTest {
   private static final Logger log = Logger.getLogger(CadastroGeralControllerTest.class);
   private Session session;
   private CadastroGeralDao dao;
   private MockResult result;
   private CadastroGeralController controller;
   private HibernateMockValidator validator;

    public CadastroGeralControllerTest() {
    }

    @Before
	public void setUp() throws Exception {    // inicia a cada teste
     
      session = CriadorSession.getSession();      // TODO - uma classe que cria a session - podia colocar somente no inicio do teste, mas depois mudo isto.
	session.beginTransaction();               // pra não deixar nada no banco   ???? 
      
	dao = new CadastroGeralDao(session);      // um dao concreto, ainda não sei usar o mockito

      result = new MockResult();
       validator = new HibernateMockValidator();  // um mock do hibernate

      controller = new CadastroGeralController(dao, validator, result);  // o controler
   }


    @After
   public void tearDown() throws Exception {
      if (session != null && session.getTransaction().isActive()) {
         session.getTransaction().rollback();
      }
    }

  
    @Test                                                                                 // o teste devia passar pois é criado um cadastro válido
    public void AdicionarNovoCadastro(){                                
       CadastroGeral cad = new CadastroGeral("teste nome", "[telefone removido]");
       controller.salva(cad);
       assertTrue(dao.existeCadastroPorCpfCnpj("[telefone removido]"));
    }

    @Test(expected=ValidationException.class)                            // o teste devia passar pois a classe validator devia gerar o erro esperado
    public void AdicionaComNomeNulo(){
       CadastroGeral cad = new CadastroGeral( );
       cad.setCpfcnpj("[telefone removido]");
       controller.salva(cad);
    }

}
A

Estou terminando uma pericia contábil que preciso entregar.

A tarde vou atualizar o git e fazer estes testes… depois eu posto o resultado.

Lucas_Cavalcanti

o método HibernateMockValidator#validate não deveria soltar exceção, justamente pq o Validator#validate nunca solta exceção.
O Mock estaria com um comportamento não real.

o que eu fiz no vraptor/master foi adicionar os erros de validação na lista de erros, assim quando vc chama o validator.onErrorUse… ele lança a exceção correta

G

Lucas Cavalcanti:
o método HibernateMockValidator#validate não deveria soltar exceção, justamente pq o Validator#validate nunca solta exceção.
O Mock estaria com um comportamento não real.

o que eu fiz no vraptor/master foi adicionar os erros de validação na lista de erros, assim quando vc chama o validator.onErrorUse… ele lança a exceção correta

Se estamos falando da mesma coisa, o Hibernate Validator / Bean Validator retorna um getViolations apenas com uma lista de “erros de validação”.

Lucas_Cavalcanti

o HibernateMockValidator que está no vraptor usa os componentes do vraptor pra fazer isso, então ele retorna erros como Message mesmo

A

adicionei os logs abaixo e verifiquei que a chamada ao metodo

na classe HibernateMockValidator não está adicionando as mensagens de erro na variavel “errors” da classe MockValidator

public <T extends View> T onErrorUse(Class<T> view) {
		log.debug("inicio onErrorUse");
		log.debug("erros: " + this.errors.size());
		if(!this.errors.isEmpty()) {
			
			throw new ValidationException(errors);
		}
		log.debug("fim onErrorUse - retornando MockResult().use(view)");
		return new MockResult().use(view);
		
	}

vou tentar descobri o motivo, mas se alguem conseguir descobrir antes, posta ai

Lucas_Cavalcanti

essa chamada:

hibernateValidator3.validate(bean)

retorna alguma coisa?

A
coloquei um log na Classe criada pelo Garcia.
@SuppressWarnings("unchecked")
    @SuppressWarnings("unchecked")
    public List<Message> validate(Object object) {
        List<Message> errors = new ArrayList<Message>();
        ClassValidator<Object> validator = (ClassValidator<Object>) locator.getValidator(object.getClass(), localization.getBundle());
        InvalidValue[] invalidValues = validator.getInvalidValues(object);

        for (InvalidValue value : invalidValues) {
        	
        	log.debug("entrou aqui....  ");
            errors.add(new ValidationMessage(value.getMessage(), value.getPropertyPath()));
        }
        log.debug("mensagens de erro adicionadas: " + errors.size());
        return errors;
    }
log
5:21,675 DEBUG [ValidatorLocator    ] Creating hibernate validator locator for br.com.admwagner.processos.model.CadastroGeral
16:15:21,680 DEBUG [HibernateValidator3 ] mensagens de erro adicionadas: 0
16:15:21,680 DEBUG [HibernateMockValidator] fim validate
16:15:21,682 DEBUG [MockValidator       ] inicio onErrorUse
16:15:21,682 DEBUG [MockValidator       ] erros: 0
16:15:21,683 DEBUG [MockValidator       ] fim onErrorUse - retornando MockResult().use(view)

ou seja, não está entrando no laço que adiciona as mensagens

Lucas_Cavalcanti

por que não tá dando nenhum erro? creio que o invalidValues está vazio

A

estas linhas deveria criar a lista com erros de validação que seriam então capturadas pelo laço que criaria a lista de mensagens… ou não?

ClassValidator<Object> validator = (ClassValidator<Object>) locator.getValidator(object.getClass(), localization.getBundle());  
     InvalidValue[] invalidValues = validator.getInvalidValues(object);
A

alterei a classe br.com.caelum.vraptor.validator.HibernateValidator3 e os testes junit funcionaram tantos os meus, quanto os do proprio vraptor.

estou meio sem tempo. vou tentar continuar os testes subindo a aplicação e testando na mão para ver se não vai dar mais problema.

G

Porque você está usando o Hibernate 3 Validator? Atualmente o Hibernate 4 Validator faz parte da spec do Bean Validator, sendo assim o Hibernate Validator 3 nem é mais mantido pela JBoss (pelo menos nunca mais ví nenhuma movimentação no projeto).

De qualquer forma, validator.getInvalidValues(object) retorna uma lista com todas as violações. Para você saber as violações basta percorrer essa lista.

No caso desse componente o laço for (InvalidValue value : invalidValues) adiciona cada uma dessas violações no objeto de mensagens padrão do Vraptor.

A

Bela observação!!!

garcia-jj:
Porque você está usando o Hibernate 3 Validator? Atualmente o Hibernate 4 Validator faz parte da spec do Bean Validator, sendo assim o Hibernate Validator 3 nem é mais mantido pela JBoss (pelo menos nunca mais ví nenhuma movimentação no projeto).

Na verdade estou usando o HV4, talves por isso os testes tenham falhado.
Garcia, a classe que implementa o hv4 é a JSR303Validator?

G

Sim, essa mesma.

G

Analisando os fontes a MockValidatorHibernate com a JSR303Validator, ambos tem um código muito semelhante.

A diferenças que notei são:

  • a JSR303Validator faz um MessageInterpolator para pegar as mensagens de erro localizadas. A MockValidatorHibernate não.
  • A JSR303Validator apenas adiciona as mensagens de erro no Validation, já a MockValidatorHibernate lança uma exception.

Sendo assim, o MockValidatorHibernate é realmente necessário?

Lucas_Cavalcanti

a idéia era ter um HibernateMockValidator e um JSR303MockValidator…

assim contemplaria tanto quem usa HV3 qto HV4

G

Lucas Cavalcanti:
a idéia era ter um HibernateMockValidator e um JSR303MockValidator…

assim contemplaria tanto quem usa HV3 qto HV4

Mas a HibernateMockValidator usa o Bean Validator, e não o Hibernate Validator 3x. Além disso o conteúdo das classes JSR303Validator e MockValidatorHibernate são muito parecidas, ambas chamam as APIs do Bean Validator, a diferença é que uma retorna os erros e a outra lança uma exception. É isso mesmo?

Lucas_Cavalcanti

https://github.com/caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/util/test/HibernateMockValidator.java

usa HV3, não bean validator.

daí é só criar um pro bean validator

G

Lucas Cavalcanti:
https://github.com/caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/util/test/HibernateMockValidator.java

usa HV3, não bean validator.

daí é só criar um pro bean validator

Eu estava olhando uma versão antiga dessa classe, sorry. :oops:

G

Lucas Cavalcanti:
https://github.com/caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/util/test/HibernateMockValidator.java

usa HV3, não bean validator.

daí é só criar um pro bean validator

Estive fazendo umas pesquisas… o Hibernate Validator 3x não é mais suportado pela JBoss. Desde 2008 não há mais atualizações e removeram todos os links do site Hibernater.org. Não sei se vale a pena investir em componentes para algo que está depreciated.

Lucas_Cavalcanti

tem razão, mas esse HibernateMockValidator não é um componente novo, é um suporte pra testes, que só delega pra um componente que já existe.

Criado 3 de fevereiro de 2011
Ultima resposta 8 de fev. de 2011
Respostas 24
Participantes 3