JUnit: o que é, conceitos-chave e como funciona

Autor: IT Sectr Publicado: 2026-04-08 Tempo de leitura: 8 min

JUnit é um framework padrão para testes unitários no ecossistema Java e Kotlin, usado no desenvolvimento Android para verificar a lógica de negócios ao nível de componentes isolados. O framework fornece um conjunto de anotações, métodos de asserção e um Test Runner para descoberta e execução automática de testes. De acordo com JUnit.org, a biblioteca continua sendo a solução mais popular para testes unitários no ecossistema JVM: mais de 70% dos projetos Java usam JUnit em alguma versão.

Principais pontos

  • JUnit é um framework de código aberto para testes unitários de código Java e Kotlin.
  • Anotações — @Test, @BeforeEach, @BeforeAll gerenciam o ciclo de vida da classe de teste.
  • Asserções — assertEquals, assertTrue, assertThrows verificam os resultados esperados da execução.
  • Testes parametrizados — permitem executar um mesmo teste com diferentes conjuntos de dados de entrada.
  • Test Runner — a infraestrutura do JUnit encontra e executa automaticamente todos os testes no projeto.

O que é JUnit?

JUnit é um framework de código aberto para escrever e executar testes unitários repetíveis em Java e Kotlin. Faz parte do ecossistema xUnit, uma família de frameworks baseados na arquitetura de Kent Beck e Erich Gamma, e é a ferramenta de teste padrão no Android Studio e IntelliJ IDEA.

A principal tarefa do JUnit é isolar um pequeno fragmento de código (método, classe) e verificar seu comportamento em condições controladas. Os testes são escritos como classes Java/Kotlin comuns com anotações, e o framework cuida da descoberta de testes, gerenciamento do ciclo de vida e coleta de estatísticas de execução.

A primeira versão do JUnit apareceu em 1997 e mudou radicalmente a abordagem de desenvolvimento, popularizando as práticas de Test-Driven Development (TDD). Hoje, o JUnit 5 (Jupiter) é a versão atual, completamente redesenhada com uma arquitetura modular compatível com Java 8+ e extensões.

Como o JUnit funciona

O mecanismo de execução do JUnit é baseado no padrão Test Runner, que escaneia o classpath, encontra métodos com a anotação @Test, cria uma instância da classe de teste e executa os métodos em uma ordem específica. O Test Runner gerencia o ciclo de vida: BeforeAll → BeforeEach → Test → AfterEach → AfterAll.

Ciclo de vida da classe de teste

O JUnit envolve cada método de teste em uma instância de classe separada, garantindo o isolamento entre os testes. Isso significa que os campos da classe não mantêm estado entre diferentes métodos @Test — cada teste começa com um objeto limpo.

Estrutura básica do teste

O teste mais simples no JUnit é um método com a anotação @Test que chama o código sob teste e verifica o resultado usando uma asserção. Se a asserção falhar, o teste é considerado falho e o JUnit reporta o erro.

java
@Test
void additionShouldReturnCorrectSum() {
    var calculator = new Calculator();
    var result = calculator.add(2, 3);
    assertEquals(5, result);
}

O Test Runner encontra automaticamente tal método, executa-o e reporta o resultado. Se o método não lançar uma exceção — o teste passa (green). Se uma asserção falhar — o teste falha (red).

Anotações do JUnit: ciclo de vida do teste

As anotações do JUnit definem quando e como o código de teste deve ser executado. No JUnit 5, as anotações estão no pacote org.junit.jupiter.api e cobrem todas as etapas: preparação de dados, execução do teste, limpeza de recursos.

AnotaçãoPropósitoExecuta
@TestMarca um método de testeUma vez por chamada
@BeforeEachPreparação antes de cada testeAntes de cada @Test
@BeforeAllInicialização única da classeUma vez antes de todos os testes
@AfterEachLimpeza após cada testeApós cada @Test
@AfterAllFinalização única da classeUma vez após todos os testes
@DisplayNameNome legível do testeDecoração

Exemplo de uso de anotações

Considere uma classe de teste completa com um ciclo de vida adequado. O método setUp cria uma nova instância de Calculator antes de cada teste, e tearDown libera recursos — por exemplo, fechando descritores de arquivo ou conexões de banco de dados.

java
class CalculatorTest {

    private Calculator calculator;

    @BeforeEach
    void setUp() {
        calculator = new Calculator();
    }

    @Test
    void subtractionShouldReturnCorrectResult() {
        int result = calculator.subtract(10, 4);
        assertEquals(6, result);
    }

    @AfterEach
    void tearDown() {
        calculator.reset();
    }
}

Asserções: verificação de resultados no JUnit

Asserções são métodos estáticos que comparam o resultado real com o esperado e lançam uma exceção se não coincidirem. O JUnit 5 oferece a classe org.junit.jupiter.api.Assertions com mais de 25 métodos para diferentes cenários de verificação — desde a comparação simples de valores até verificações de tempo limite e asserções agrupadas.

  • assertEquals(expected, actual) — verifica igualdade via equals().
  • assertTrue(condition) — verifica que uma condição é verdadeira.
  • assertFalse(condition) — verifica que uma condição é falsa.
  • assertNotNull(object) — verifica que um objeto não é null.
  • assertNull(object) — verifica que um objeto é null.
  • assertThrows(exception, executable) — verifica que o código lança uma exceção específica.
  • assertAll(executables) — agrupa múltiplas asserções e executa todas sem parar na primeira falha.

assertThrows para verificação de exceções

Especial atenção merece o método assertThrows, que permite verificar que o código lida corretamente com situações de erro — divisão por zero, passagem de null, exceder limites.

java
@Test
void divisionByZeroShouldThrowException() {
    Calculator calc = new Calculator();

    ArithmeticException exception = assertThrows(
        ArithmeticException.class,
        () -> calc.divide(10, 0)
    );

    assertEquals("Cannot divide by zero", exception.getMessage());
}

Testes parametrizados no JUnit

Testes parametrizados permitem executar o mesmo método de teste com diferentes conjuntos de argumentos. No JUnit 5, isso é feito usando a anotação @ParameterizedTest combinada com uma fonte de dados — @ValueSource, @CsvSource, @MethodSource ou @EnumSource.

Essa abordagem reduz radicalmente a duplicação de código: em vez de dez testes idênticos para valores diferentes, escreve-se um único método parametrizado. De acordo com o Google Testing Blog, a parametrização reduz o volume de código de teste em 40–60% sem perder cobertura.

Exemplo com CsvSource

A anotação @CsvSource passa múltiplas linhas separadas por vírgula para o teste. Cada linha corresponde a uma execução do teste. O JUnit converte automaticamente os valores de string para os tipos necessários: int, long, String e outros.

java
@ParameterizedTest
@CsvSource({
    "1,    1,   2",
    "2,    3,   5",
    "10,  20,  30",
    "-1,   1,   0"
})
void additionWithMultipleInputs(int a, int b, int expected) {
    assertEquals(expected, a + b);
}

MethodSource para objetos complexos

Quando os dados de entrada são mais complexos que números ou strings simples, usa-se @MethodSource. Ele referencia um método estático que retorna um Stream de argumentos — por exemplo, um Stream de Arguments ou um Stream de objetos User para testar a camada DAO.

Integração do JUnit com projetos Android

No desenvolvimento Android, JUnit é usado junto com AndroidX Test, que fornece extensões para testar Activity, Content Provider e outros componentes Android. O JUnit cuida dos testes unitários executados na JVM sem emulador, enquanto o AndroidX Test cuida dos testes instrumentados no dispositivo.

Configuração do Gradle

Para adicionar JUnit 5 a um projeto Android, basta incluir a dependência org.junit.jupiter:junit-jupiter no build.gradle nível de módulo. O plugin AGP do Gradle suporta a execução de testes JUnit 5 na JVM através do Test Runner padrão.

kotlin
// build.gradle.kts
android {
    testOptions {
        unitTests.isIncludeAndroidResources = true
    }
}

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter:5.11.0")
    testImplementation("androidx.test:core-ktx:1.6.1")
}

Testando ViewModel com JUnit

Na prática, o JUnit é mais frequentemente usado para testar ViewModel e repositórios — camadas que não requerem contexto Android ou emulador. Esse tipo de teste é executado em milissegundos e pode ser executado centenas de vezes sem perder tempo.

  • ViewModel — verificação de estados: loading, success, error.
  • Repository — verificação de mapeamento de dados e tratamento de erros.
  • UseCase — verificação de lógica de negócios com mocks de dependências.

JUnit 4 vs JUnit 5: diferenças principais

JUnit 5 (Jupiter) não é apenas uma nova versão, mas uma plataforma completamente redesenhada dividida em três módulos: JUnit Platform (execução de testes na JVM), JUnit Jupiter (API para escrever testes) e JUnit Vintage (compatibilidade reversa com JUnit 4). Essa modularidade permite conectar diferentes Test Engines — por exemplo, Spek para Kotlin ou TestNG.

CaracterísticaJUnit 4JUnit 5
Pacoteorg.junitorg.junit.jupiter
Anotação base@Test (de junit.framework)@Test (de org.junit.jupiter.api)
Before/After@Before, @After, @BeforeClass@BeforeEach, @AfterEach, @BeforeAll
Parametrizados@RunWith(Parameterized.class)@ParameterizedTest + @ValueSource
Extensão@Rule, @ClassRule@ExtendWith, API mais flexível
Java minJava 5Java 8+

Migrar do JUnit 4 para o JUnit 5 não requer reescrever todos os testes — basta adicionar JUnit Vintage Engine e os testes antigos continuarão funcionando. Novos testes são recomendados para serem escritos com JUnit 5 para aproveitar extensões, asserções lambda e suporte integrado a parametrização.

Perguntas frequentes

Como o JUnit difere do Mockito?

JUnit é um framework para escrever e executar testes, enquanto Mockito é uma biblioteca para criar objetos mock. Eles são usados juntos: JUnit gerencia a execução do teste e Mockito substitui as dependências da classe sob teste.

Pode-se usar JUnit 5 em projetos Android?

Sim, o JUnit 5 é totalmente compatível com projetos Android. Para testes unitários, basta adicionar a dependência junit-jupiter no build.gradle. Testes instrumentados continuam funcionando através do AndroidX Test Runner.

Qual é o conjunto mínimo de anotações necessário para um teste?

No mínimo, uma única anotação @Test antes do método é suficiente. Para inicialização e limpeza, recomenda-se @BeforeEach e @AfterEach, mas não são obrigatórias.

O que é o Test Runner no JUnit?

O Test Runner é um componente do JUnit que escaneia o classpath, encontra métodos com a anotação @Test, cria instâncias de classes de teste e executa os testes. No JUnit 5, esse papel é desempenhado pela JUnit Platform com Test Engines conectados.

Como verificar que um método lança uma exceção?

Use assertThrows(Class, Executable) — ele aceita o tipo de exceção esperada e uma lambda com a chamada do método. O JUnit verifica que a exceção foi realmente lançada e a retorna para inspeção adicional.

Resumo

  • JUnit é o framework padrão de testes unitários para Java e Kotlin, base do ecossistema xUnit.
  • Anotações @Test, @BeforeEach, @AfterEach gerenciam o ciclo de vida da classe de teste.
  • Asserções — assertEquals, assertTrue, assertThrows verificam a correção dos resultados.
  • Testes parametrizados com @CsvSource e @MethodSource reduzem a duplicação de código.
  • JUnit 5 — arquitetura modular com plataforma, API Jupiter e suporte a extensões.
  • Integração Android — JUnit executa na JVM através do Test Runner padrão sem emulador.
  • Test Runner descobre e executa automaticamente métodos @Test, reportando resultados.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também