4.3 Testando cenários mais complexos

Vamos agora começar a testar nosso LeilaoDao. Um dos métodos desse DAO retorna a quantidade de leilões que ainda não foram encerrados. Veja:

public Long total() {
 
return (Long) session.createQuery("select count(l) from "+
 
"Leilao l where l.encerrado = false")
 
}
 
Ele faz um simples SELECT COUNT. Para testar essa consulta, adicionaremos dois leilões: um encerrado e outro não encerrado. Dado esse cenário, esperamos que o método total() nos retorne 1. Vamos ao teste.
 
Repare que, para criar um Leilão, precisaremos criar um Usuário e persisti-lo no banco também, afinal o Leilão referencia um Usuário; para fazer
 

isso, utilizaremos o UsuarioDao, que sabe persistir um Usuario!

Essa é uma das dificuldades de se escrever um teste de integração: montar cenário é mais difícil. Dê uma olhada no código a seguir, ele é extenso, mas está comentado:

public

class LeilaoDaoTests { private Session session; private LeilaoDao leilaoDao; private UsuarioDao usuarioDao;
 
@Before
 
public void antes() {
 
    session = new CriadorDeSessão().getSession(); leilaoDao = new LeilaoDao(session); usuarioDao = new UsuarioDao(session);
 
}

@After

public void depois() { session.close();
 
}
 
@Test
 
public void deveContarLeiloesNaoEncerrados() {
 
// criamos um usuario Usuario mauricio =
 
new Usuario("", "mauricio@aniche.com.br");
 
// criamos os dois leiloes Leilao ativo =
 
new Leilao("Geladeira", 1500.0, mauricio, false); Leilao encerrado =
 
new Leilao("XBox", 700.0, mauricio, false); encerrado.encerra();
 
// persistimos todos no banco usuarioDao.salvar(mauricio); leilaoDao.salvar(ativo); leilaoDao.salvar(encerrado);
 
// invocamos a a�ao que queremos testar
 
// pedimos o total para o DAO long total = leilaoDao.total();
 
assertEquals(1L, total);
 
}
 
}
 
Se rodarmos o teste, ele passa!
 

Mas esse teste ainda não está legal. Nesse momento, ele passa porque estamos rodando-o usando o banco de dados HSQLDB. Se estivéssemos rodando em um MySQL, por exemplo, esse teste poderia falhar. Cada vez que rodamos o teste, ele insere 2 linhas no banco de dados. Se rodarmos o teste 2 vezes, por exemplo, teremos 2 leilões não encerrados, o que faz com que o teste falhe:

A melhor maneira de garantir que, independente do banco em que você esteja rodando o teste, o cenário esteja sempre limpo para aquele teste. É ter a base de dados limpa. Um jeito simples de fazer isso é executar cada um dos testes dentro de um contexto de transação e, ao final do teste, fazer um “rollback. Com isso, o banco rejeitará tudo o que aconteceu no teste e continuará limpo.

Isso é fácil de ser implementado. Basta mexermos nos métodos @Before

e After:

@Before

public void antes() {
 
session = new CriadorDeSessão().getSession(); leilaoDao = new LeilaoDao(session); usuarioDao = new UsuarioDao(session);
 
// inicia transa�ao session.beginTransaction();
 
}
 
@After
 
public void depois() {
 
// faz o rollback session.getTransaction().rollback(); session.close();
 
}
 

Pronto. Agora, mesmo no MySQL, esse teste passaria. Iniciar e dar rollback na transação durante testes de integração é prática comum. Faça uso do @Before e @After para isso, e dessa forma, seus testes ficam independentes e fáceis de manter.

Usar ou não usar HSQLDB?

Os desenvolvedores se dividem muito entre usar HSQLDB ou o banco de produção nos testes. A vantagem do HSQLDB é clara: o teste roda muito mais rápido, afinal ele é um banco de dados em memória, muito mais leve.

No entanto, sou mais favorável a testes de integração que realmente façam uso do mesmo banco que a aplicação que será usada em produção. Apesar dos testes ficarem mais lerdos, o feedback é maior. Na prática, sabemos que algumas consultas SQL são dependentes de banco, e que, em um caso extremo, o resultado pode ser diferente.

Portanto, se estou pagando o custo de fazer um teste de integração, prefiro que ele seja o mais real possível.


⬅️ Capítulo Anterior | Próximo Capítulo ➡️