Testes DAO com Spring e Hibernate

3 respostas
alex_luiz

Olá a todos…

Atualmente faço somente testes de sistema, mas tenho que fazer testes nos DAO’s da aplicação…

Segue abaixo um exemplo de um model e um DAO:

Model:

@Entity
@Table(name = "cp_acoes", uniqueConstraints = @UniqueConstraint(columnNames = "nome"))
@SequenceGenerator(initialValue=1, name="idgen", sequenceName="seq_acao")
public class Acao extends BaseEntity implements java.io.Serializable {

	/** generated serial version id	 */
	private static final long serialVersionUID = 4644023237164063450L;
	private Integer id;
	private String nome;
	
	/**
	 * Construtor padrao
	 */
	public Acao() {
	}

	/**
	 * 
	 * @param nome
	 */
	public Acao(String nome) {
		this.nome = nome;
	}

	/**
	 * @return pk id
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO, generator="idgen")
	@Column(name = "id")
	public Integer getId() {
		return this.id;
	}

	/**
	 * set id
	 * @param id
	 */
	public void setId(Integer id) {
		this.id = id != null && id == 0 ? null : id;
	}

	/**
	 * @return nome
	 */ 
	@YepSearch(matchMode=Mode.ANYWHERE)
	@Column(name = "nome", length = 100)
	public String getNome() {
		return this.nome;
	}

	/**
	 * set nome
	 * @param nome
	 */
	public void setNome(String nome) {
		this.nome = nome;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((nome == null) ? 0 : nome.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Acao other = (Acao) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (nome == null) {
			if (other.nome != null)
				return false;
		} else if (!nome.equals(other.nome))
			return false;
		return true;
	}

}

DAO:

@Repository
public class AcoesDao extends GenericDaoImpl<Acao> {

	/**
	 * Default constructor
	 * @param factory
	 */
	@Autowired
	public AcoesDao(@Qualifier("sessionFactory")SessionFactory factory) {
		super(factory);
	}

	@Override
	protected Class<Acao> getEntityClass() {
		return Acao.class;
	}

	@Override
	public Serializable getPrimaryKeyValue(Acao obj) {
		return obj.getId();
	}
	
	public List<Acao> getListAdvanced(Acao searchObject, int start, int limit) throws SQLException {

		
		DetachedCriteria criteria = createYepSearchCriteria(searchObject);
		
		List<Acao> rsAcoes = (List<Acao>) getHibernateTemplate().findByCriteria(criteria,start,limit);
		if (rsAcoes.isEmpty())
			return null;

		return rsAcoes;
	}
}

GenericDaoImpl:

@Repository
public abstract class GenericDaoImpl<Entity> extends GenericWorkDao
implements GenericDao<Entity> {

	protected Log log = LogFactory.getLog(this.getClass());
	protected UserSessionListener userListener;
	protected ApplicationConfig appConfig;
	
	/**
	 * @param userListener the userListener to set
	 */
	@Autowired
	public void setUserListener(UserSessionListener userListener) {
		this.userListener = userListener;
	}
	
	/**
	 * @param appConfig
	 */
	@Autowired
	public void setAppConfig(ApplicationConfig appConfig) {
		this.appConfig = appConfig;
	}
	
	/**
	 * IoC SessionFactory
	 * 
	 * @param factory
	 */
	@Autowired
	public GenericDaoImpl(@Qualifier("sessionFactory") SessionFactory factory) {
		super(factory);
	}

	/**
	 * Este metodo deve ser sobrescrito na classe filha, para retornar a chave
	 * unica atraves de uma instancia de Entity
	 * 
	 * @param obj
	 *            objeto contendo uma chave primaria
	 * @return valor da chave primaria
	 */
	abstract public Serializable getPrimaryKeyValue(Entity obj);

	/**
	 * Retorna .class da entidade relacionada a este dao deve ser implementado
	 * na classe filha
	 * 
	 * @return .class da entidade relacionada a este Dao
	 */
	protected abstract Class<Entity> getEntityClass();

	/**
	 * Find item by id
	 */
	@SuppressWarnings("unchecked")
	public Entity findById(Entity obj) throws PerceptToolsException {
		Serializable key = getPrimaryKeyValue(obj);
		Entity retVal = null;
		
		retVal = (Entity) getHibernateTemplate().get(getEntityClass(), key);

		return retVal;
	}
	
	public Entity getById(Serializable key) throws PerceptToolsException {
		Entity retVal = null;
		
		retVal = (Entity) getHibernateTemplate().get(getEntityClass(), key);

		return retVal;
	}

	/**
	 * Retorna a lista de todos os objetos no banco de dados
	 * 
	 * @return lista de todos os objetos salvos em banco
	 * @throws PerceptToolsException
	 */
	@SuppressWarnings("unchecked")
	public List<Entity> getList() throws PerceptToolsException {
		return getHibernateTemplate().loadAll(getEntityClass());
	}

	/**
	 * Persiste um objeto no banco. Insere ou atualiza
	 * 
	 * @param obj
	 *            objeto a ser salvo
	 * @return objeto salvo com id populado no caso de insercao
	 * @throws PerceptToolsException
	 * @throws SQLException 
	 */
	public Entity save(Entity obj) throws PerceptToolsException {
		getHibernateTemplate().saveOrUpdate(obj);
		return obj;
	}

	/**
	 * Remover um objeto do banco de dados
	 * 
	 * @param obj
	 *            objeto a ser removido
	 * @throws PerceptToolsException
	 */
	public void remove(Entity obj) throws PerceptToolsException {
		getHibernateTemplate().delete(obj);
	}

	/**
	 * Retorna itens filtrando pelo nome da propriedade
	 * 
	 * @param propertyName
	 *            nome da propriedade
	 * @param value
	 *            valor da propriedade
	 * @return lista de itens filtrados, ou lista vazia no caso de nenhum
	 *         resultado
	 * @throws PerceptToolsException
	 */
	@SuppressWarnings("unchecked")
	public List<Entity> findAllByProperty(String propertyName, Object value)
	throws PerceptToolsException {
		return this.findAllByProperty(propertyName, value, 0, 0);
	}

	public List<Entity> findAllByProperty(String propertyName, Object value, int firstResult,
			int maxResults)
			throws PerceptToolsException {		
		DetachedCriteria criteria = createDetachedCriteria();
		criteria.add(Restrictions.eq(propertyName, value));
		criteria.setResultTransformer(DistinctRootEntityResultTransformer.INSTANCE);
		return getHibernateTemplate().findByCriteria(criteria,firstResult,maxResults);
	}

	/**
	 * Retorna itens filtrando pelo nome da propriedade string utilizado o MatchMode definido
	 * 
	 * @param propertyName
	 *            nome da propriedade
	 * @param value
	 *            valor da propriedade
	 * @param matchMode 
	 * @return lista de itens filtrados, ou lista vazia no caso de nenhum
	 *         resultado
	 * @throws PerceptToolsException
	 */
	@SuppressWarnings("unchecked")
	public List<Entity> findAllByProperty(String propertyName, String value, MatchMode matchMode)
	throws PerceptToolsException {
		DetachedCriteria criteria = createDetachedCriteria();
		criteria.add(Restrictions.like(propertyName, value,matchMode));
		return getHibernateTemplate().findByCriteria(criteria);
	}

	/**
	 * Pesquisar items no banco atraves de um objeto exemplo
	 * 
	 * @param object
	 *            objeto exemplo
	 * @return itens que correspondem ao objeto modelo
	 * @throws PerceptToolsException
	 */
	public List<Entity> findByExample(Entity object)
	throws PerceptToolsException {
		return findByExample(object, 0, Integer.MAX_VALUE);
	}
	
	
	@SuppressWarnings("unchecked")
	public List<Entity> findAllByProperties(Map<String, Object> values)
	throws PerceptToolsException {
		DetachedCriteria criteria = createDetachedCriteria();
		
		for(String key: values.keySet()) {
			criteria.add(Restrictions.eq(key, values.get(key)));
		}
		
		return getHibernateTemplate().findByCriteria(criteria);
	}

	/**
	 * Pesquisar itens atraves de um objeto exemplo definindo um limite de
	 * resultados
	 * 
	 * @param object
	 *            objeto de exemplo
	 * @param firstResult
	 *            indice do objeto inicial
	 * @param maxResults
	 *            maximo de resultados a ser retornado
	 * @return lista com objetos encotrados ou lista vazia
	 * @throws PerceptToolsException
	 */
	@SuppressWarnings("unchecked")
	public List<Entity> findByExample(Entity object, int firstResult,
			int maxResults) throws PerceptToolsException {
		List<Entity> resultList = null;

		try {
			resultList = getHibernateTemplate().findByExample(object,firstResult, maxResults);
		} catch( HibernateException e) {
			throw new PerceptToolsException(e.getMessage());
		}

		return resultList;
	}
	
	public List<Entity> findByYepSearch(Entity object, int firstResult, int maxResults) {
		List<Entity> resultList = null;
		
		DetachedCriteria criteria = createYepSearchCriteria(object);
		
		resultList = getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults);
		
		return resultList;
	}
	
	public Integer countByYepSearch(Entity object) {
		Integer retVal = null;
		
		DetachedCriteria criteria = createYepSearchCriteria(object);
		criteria.setProjection(Projections.rowCount()); 
		
		List<Integer> rs = (List<Integer>) getHibernateTemplate().findByCriteria(criteria);
		if(rs != null && rs.size() > 0) {
			retVal = rs.get(0);
		}
		
		return retVal;
	}
	

	protected DetachedCriteria createDetachedCriteria()
	throws PerceptToolsException {
		try {
			setCaseInsensitiveOracle();
		} catch (SQLException e) {
			System.out.println("Search Case Insensitive is not executed" + e.getMessage());
		}
		return DetachedCriteria.forClass(getEntityClass());
	}
	
	protected Object autoMergeEntity(Object obj) throws PerceptToolsException {
		return getHibernateTemplate().merge(obj);
	}
	
	/**
	 * Helper that return the current logged user
	 * @return
	 */
	protected User getLoggedUser() {
		return userListener.getUserFromPool(FlexContext.getFlexClient().getId());
	}
	
	public String createYepSearchQuery(Entity object) {
	
		String query = "";
		HashMap<String, String> map = new HashMap<String, String>();
		
		try {
			query = YepSearchQueryBuilder.fillCriteria(object, map); 
		
		} catch (Exception e) {
			log.fatal("Erro",e);
			throw new PerceptToolsException("Erro utilizando YepSearch",e);
		}
		
		return query;
		
	}
	
	public void flush() {
		getHibernateTemplate().flush();
	}
	
	private void setCaseInsensitiveOracle() throws SQLException {
		if (appConfig.getString(ConfigName.APP_BANCO_DADOS).equalsIgnoreCase("Oracle")) {
			String sql1 = "ALTER SESSION SET NLS_COMP=LINGUISTIC";
			String sql2 = "ALTER SESSION SET NLS_SORT=BINARY_CI";
			
			executeSQLWork(sql1);
			executeSQLWork(sql2);
		}
	}
	
	@SuppressWarnings("deprecation")
	private void executeSQLWork(final String sql) throws SQLException {
		PreparedStatement pStatement = null;
		try {
			pStatement = getHibernateTemplate().getSessionFactory().getCurrentSession().connection().prepareStatement(sql);			
			
			pStatement.executeUpdate();			
		} catch (SQLException e) {
			throw new SQLException("Search Case Insensitive is not executed");
		} finally {
			try { pStatement.close(); } catch (Exception e) { /*do nothing*/ }
		}
	}

}

Estou fazendo um teste simples do método save:

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;

import com.yepdev.percepttools.cadastroprocesso.model.dao.AcoesDao;
import com.yepdev.percepttools.cadastroprocesso.model.entity.Acao;
  
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:*/applicationContextTest2.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class AcoesDaoTest {

	private Acao acao;
	private AcoesDao dao;

	public AcoesDao getAcoesDao(AcoesDao dao) {
		
		return dao;
	}
	
	@Test
	public void testSaveAcao() {
		
		acao = new Acao();
		acao.setId(2);
		acao.setNome("Teste");
		
		this.getAcoesDao(dao).save(acao);
	}

}

Alguém poderia me ajudar??

3 Respostas

Dapcapix

Amigão,

Eu vi que você é novo no fórum e passei pelo mesmo problema no começo.

Antes do código que você colar aqui coloque entre as tags Code (logo abaixo do assunto tem o botão) e fecha no final do código.

Fica melhor de visualizar.

alex_luiz

Obrigado pela dica

ErickRAR

log.fatal("This is impossible! Pau no software",e);
:lol:

Enfim, é um teste formal? Se for isso, procure por Roteiro de testes, analise o que deve ser testado e a prioridade e mãos à obra.
Se for só um teste rápido, pra ver se está funcionando e tal, sem muita burocracia, crie um main, um objeto Acao e vá testando.

Teste incluir, alterar, pesquisar etc. teste com dados corretos, com dados incorretos, possíveis falhas(e impossíveis também), verifique o tempo de resposta, essas coisas.

EDIT: Talvez isso seja importante: Acho que alguns métodos ai não podem ser public. Devem ser trocados por protected ou private. Mas tudo depende do contexto e da aplicação…

Criado 24 de maio de 2012
Ultima resposta 25 de mai. de 2012
Respostas 3
Participantes 3