Como escrever testes unitários em Java
Lewis Gavin
18 de novembro de 2022
0 minutos de leituraTestar é uma prática recomendada essencial no desenvolvimento de software. Os testes unitários são uma das várias estratégias que podemos usar para garantir que nosso código seja funcional e eficiente. Como pessoas desenvolvedoras, podemos escrever testes unitários para verificar componentes individuais (unidades) do código da aplicação, como um método específico. A ideia é escrever um ou mais testes unitários para cada parte do código e executá-los sempre que houver uma alteração, para detectar defeitos assim que forem introduzidos na base de código. Para código novo, os testes devem ser adicionados enquanto o código é escrito (ou até mesmo antes). Para código existente, se ainda não houver testes, eles devem ser adicionados para cobrir muitos — se não todos — os caminhos de execução da lógica da aplicação.
Os testes unitários têm como objetivo eliminar todas as dependências externas e confirmar que um trecho específico do código se comporta como esperado em diferentes situações. Isso pode envolver chamar um método repetidamente, cada vez com novos parâmetros, e verificar se ele retorna o valor correto, lança uma exceção ou executa uma tarefa específica.
Entre os frameworks de testes unitários disponíveis, muitos desenvolvedores Java usam o JUnit. Neste post, vamos aprender a instalar e usar o JUnit 5 para escrever testes unitários para um código Java. Vamos usar o ambiente de desenvolvimento integrado (IDE) VSCode para escrever os testes e o Java 11 com Maven para executá-los. No entanto, ferramentas como Eclipse e IntelliJ funcionam de maneira semelhante e também permitem acompanhar o tutorial.
Para conhecer mais ferramentas de análise de código Java, confira nossas ferramentas de revisão de código Java ou nosso artigo sobre segurança em Java para aprender os conceitos básicos.
Como escrever seu primeiro teste unitário em Java
Nesta seção, vamos instalar o framework JUnit e escrever alguns testes unitários. Mais adiante, vamos executar os testes neste projeto de código de exemplo. O projeto já vem configurado com o código da aplicação e um modelo de classe de teste com tudo o que precisamos para começar a adicionar testes.
Primeiro, antes de começar a escrever os testes, vamos analisar o código de exemplo.
Nossa aplicação tem um método main que chama o método generateUpdateUserFirstNameStatement e exibe o resultado. Se uma chamada ao método generateUpdateUserFirstNameStatement gerar um erro, a aplicação captura a exceção e exibe o rastreamento da pilha.
O método generateUpdateUserFirstNameStatement é simples: recebe dois parâmetros do tipo string e os usa para gerar uma instrução SQL UPDATE. O código gera um erro se algum dos parâmetros contiver ponto e vírgula, pois isso provavelmente indica uma tentativa de injeção de SQL.
Esse método é um excelente exemplo de caso de uso para testes unitários, pois queremos confirmar seu funcionamento em dois cenários. Primeiro, quando passamos duas strings comuns como parâmetros, esperamos receber uma string que contenha a instrução SQL. Depois, quando fornecemos como segundo parâmetro uma string que contém uma injeção de SQL, esperamos que o método gere um erro. Podemos testar ambos os casos com testes unitários.
Para começar, precisamos instalar alguns pacotes Maven, incluindo o maven-surefire-plugin, que inclui a biblioteca JUnit. Também precisamos informar ao Maven que nossa aplicação depende do JUnit durante a execução dos testes.
Vamos abrir o arquivo pom.xml fornecido e adicionar o código de dependência a seguir na seção correspondente, na linha 21.
Quando terminar, salve o arquivo.
Agora podemos usar o Maven para instalar os pacotes. Para fazer isso no VSCode, expanda o menu Maven no canto inferior esquerdo, clique com o botão direito do mouse no projeto e selecione install. Se você estiver usando outra IDE, o processo pode ser diferente.

Se não souber como fazer isso na sua IDE, você também pode instalar as dependências pela linha de comando. No terminal, acesse o diretório raiz do projeto e execute o seguinte comando Maven para instalar as dependências.
Observação: se o Maven não estiver instalado na sua máquina, siga as instruções de instalação antes de executar este comando.
Ao concluir, o Maven terá instalado os plugins especificados no nosso pom.xml file, incluindo a biblioteca JUnit. Ao executar os testes, o Maven sabe que deve usar o JUnit, definido como dependência de teste por meio de <scope>test</scope> na configuração.

Como podemos ver na saída acima, ao final da instalação são exibidas as informações relacionadas aos testes. No entanto, ainda não configuramos nenhum teste, então o número de testes executados foi 0. Vamos mudar isso adicionando dois testes unitários à aplicação.
Para começar, abra o arquivo src/test/java/com/snyk/unittestdemo/AppTest.java, que o Maven executará para rodar nossos testes. Primeiro, precisamos importar os pacotes JUnit necessários. Adicione as duas importações a seguir no início do arquivo:
A primeira importação nos dá acesso à anotação de teste do JUnit, que permite definir nossos métodos como testes. A segunda importação é do método assertTrue, fornecido pelo JUnit. Usamos esse método para verificar se uma condição resulta em verdadeiro. Se sim, o teste será aprovado. Caso contrário, será reprovado.
Vamos adicionar nosso primeiro teste, que verificará se o método generateUpdateUserFirstNameStatement retorna o resultado correto quando recebe duas strings comuns. Dentro da classe AppTest, adicione o método a seguir.
Definimos o método como um teste usando a anotação @Test. Em seguida, usamos o método importado assertTrue para verificar a saída do método generateUpdateUserFirstNameStatement. Passamos duas strings — John e abcdef1234567 — e queremos verificar se a função retorna a string esperada. Se o método estiver funcionando corretamente, o teste será aprovado.
Salve o arquivo e execute o teste para verificar se ele é aprovado. No VSCode, clique com o botão direito do mouse no projeto Maven e selecione test.

Você também pode executar este comando pelo terminal. Para isso, abra o terminal, acesse a pasta do projeto e execute o seguinte comando.
Esse comando instrui o Maven a compilar a aplicação e executar os testes. A saída dos testes agora deve indicar que um teste foi executado e que não houve falhas.

Agora, vamos modificar um pouco o método generateUpdateUserFirstNameStatement, alterando a instrução UPDATE que a função retorna. Execute os testes novamente para ver como o Maven exibe uma falha.

A saída agora muda e informa que um teste falhou. Abaixo do cabeçalho Results:, você pode ver o número e os tipos de falha. Neste caso, os resultados identificam o método de teste generateUpdateUserFirstNameStatement e o número da linha em que ocorreu a falha (linha 14). Lembre-se de desfazer as alterações que fizeram a função parar de funcionar.
Também podemos testar se nossa função gera um erro como esperado, usando uma abordagem um pouco diferente do método assertTrue. Para começar, adicione o seguinte método de teste à classe de teste.
Aqui, usamos a anotação @Test para indicar um valor esperado. Esperamos que nosso método gere uma instância da classe Error, pois foi assim que programamos o tratamento de uma tentativa de injeção de SQL em qualquer um dos parâmetros. Agora podemos executar os testes e verificar se eles são aprovados.

Implementamos com sucesso nossos primeiros testes unitários em Java com JUnit. Com eles, podemos garantir que nosso código funcione como esperado e produza os resultados corretos. Se isso não acontecer, o teste será reprovado.
É essencial proteger nossas aplicações contra vulnerabilidades, como as que nos expõem a injeções maliciosas de SQL. Adicionar um teste como este pode evitar que uma pessoa desenvolvedora introduza essa vulnerabilidade no futuro. Os testes aumentam a confiança no código e oferecem uma rede de segurança para quem for desenvolvê-lo depois. Saiba mais sobre as práticas recomendadas de segurança em Java neste artigo.
Snyk Code é outra ferramenta que pode detectar práticas inseguras que talvez passem despercebidas pelas pessoas desenvolvedoras e não sejam cobertas por testes escritos. Isso inclui identificar código vulnerável a injeções de SQL e informações confidenciais inseridas diretamente no código, como segredos de API e dados de identificação pessoal.
O teste define um contrato sobre o que o método deve fazer. Se alguém quiser atualizar o método generateUpdateUserFirstNameStatement e, sem querer, comprometer seu funcionamento — como fizemos no segundo teste —, o teste unitário falhará e dará informações sobre o problema. Essa prática acrescenta uma camada de proteção contra a quebra de funcionalidades essenciais e a liberação de alterações instáveis ou perigosas em uma aplicação de produção.
Conclusão
Como aprendemos neste tutorial, escrever testes unitários é uma maneira simples de garantir que nosso código se comporte como esperado em diferentes cenários. Além disso, os testes unitários oferecem uma camada de proteção contra falhas em projetos colaborativos, evitando que outras pessoas desenvolvedoras quebrem nosso código acidentalmente ou introduzam vulnerabilidades. Embora não sejam a única forma de testar aplicações, os testes unitários devem fazer parte do conjunto de ferramentas de toda pessoa desenvolvedora.
Confira estes artigos relacionados para saber mais sobre Java:
Comece a jogar Capture the Flag
Aprenda a resolver desafios de Capture the Flag assistindo à gravação sob demanda do nosso workshop virtual introdutório.



