01. Introdução ao JUnit 6

Ao concluirmos todas as aulas deste tópico, nós:

  • Seremos capazes de descrever a estrutura de uma classe de teste no JUnit Jupiter 6, compreender seu ciclo de vida (@BeforeAll, @BeforeEach, @Test, @AfterEach, @AfterAll) e criar novas classes de teste em Kotlin.
  • Compreenderemos as responsabilidades da arquitetura do JUnit Platform e das Test Engines (substituindo os antigos @RunWith e Runner do JUnit 4).
  • Saberemos o que é uma Extensão (@ExtendWith) e como evoluir das antigas @Rule do JUnit 4 para recursos modernos como @TempDir.

Como Configurar e Inicializar o Ambiente do Projeto do Zero

Para acompanhar os exemplos e exercícios práticos deste curso com fidelidade e alta produtividade, utilizaremos uma stack moderna baseada em:

Tecnologia Versão de Referência Gerenciamento / Comando Propósito na Arquitetura
Java JDK 21 ou 25 (LTS) sdk install java 21.0.6-tem Runtime e compilador moderno da plataforma JVM gerenciado via SDKMAN.
Kotlin 2.4.21+ sdk install kotlin 2.4.21 Linguagem concisa com suporte nativo a null safety, imutabilidade e corrotinas.
Spring Boot 4.1.2+ curl https://start.spring.io/starter.zip ... Framework base para microsserviços, injeção de dependências e APIs web.
Gradle 9.8.2+ (Kotlin DSL) sdk install gradle 9.8.2 Motor de compilação modular, rápido e configurado via build.gradle.kts.
JUnit Jupiter 6.0.3+ testImplementation(libs.junit.jupiter) Motor moderno da arquitetura JUnit Platform para testes unitários na JVM.
Kotest 6.2.6+ testImplementation(libs.kotest.runner.junit5) Framework BDD idiomático em Kotlin com DescribeSpec e matchers expressivos.
AssertJ Core 3.27.7+ testImplementation(libs.assertj.core) Biblioteca de asserções fluentes com ricas mensagens diagnósticas.
MockK 1.14.0+ testImplementation(libs.mockk) Biblioteca de mocks e stubs de primeira classe para Kotlin.
Testcontainers 2.0.5+ testImplementation(libs.testcontainers.postgresql) Containers reais efêmeros (PostgreSQL) para testes de integração confiáveis.
Playwright 1.50.0+ testImplementation(libs.playwright) Automação e crawling End-to-End resiliente para Chromium, Firefox e WebKit.
Hugo 0.169.0 devbox run -- hugo Gerador estático do portal educacional e documentação de aula.

#### Gerenciamento de Versões do Java e Gradle com SDKMAN Recomendamos utilizar o [SDKMAN!](https://sdkman.io/) para instalar e alternar versões do JDK e do Gradle de forma isolada, reprodutível e sem conflitos no sistema operacional: ```bash # 1. Instale o SDKMAN (se ainda não tiver instalado) curl -s "https://get.sdkman.io" | bash source "$HOME/.sdkman/bin/sdkman-init.sh" # 2. Instale o Java JDK 21 LTS (Eclipse Temurin) sdk install java 21.0.6-tem # 3. (Opcional) Instale o Gradle e o Kotlin CLI sdk install gradle 9.8.2 sdk install kotlin 2.4.21 # 4. Defina o Java 21 como a versão ativa no seu terminal sdk use java 21.0.6-tem # 5. Valide as versões instaladas java -version gradle -version ``` > [!TIP] > **Configuração Automática via `.sdkmanrc`**: > Você pode criar um arquivo chamado `.sdkmanrc` na raiz do seu projeto com o seguinte conteúdo: > ```properties > java=21.0.6-tem > gradle=9.8.2 > ``` > Depois, basta rodar `sdk env` na pasta do projeto (ou habilitar `sdkman_auto_env=true` no arquivo `~/.sdkman/etc/config`) para que o SDKMAN selecione automaticamente o Java e Gradle corretos sempre que você entrar no diretório!

Opção A: Criação Rápida via Linha de Comando (Spring Initializr com curl)

O Spring Initializr disponibiliza uma API HTTP direta para gerar projetos prontos para compilação através de um único comando curl, dispensando qualquer interação manual com o navegador:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 1. Crie o diretório do projeto e entre nele
mkdir -p test-with-spring-starter && cd test-with-spring-starter

# 2. Faça o download do template configurado com Kotlin, Gradle Kotlin DSL e Java 21
curl https://start.spring.io/starter.zip \
  -d type=gradle-project-kotlin \
  -d language=kotlin \
  -d bootVersion=4.1.2 \
  -d jvmVersion=21 \
  -d groupId=com.testwithspring.starter \
  -d artifactId=test-with-spring-starter \
  -d name=test-with-spring-starter \
  -d packageName=com.testwithspring.starter \
  -d dependencies=web \
  -o starter.zip

# 3. Descompacte o pacote baixado e remova o arquivo zip temporário
unzip -q starter.zip
rm starter.zip

# 4. Garanta permissão de execução ao Gradle Wrapper
chmod +x gradlew
Parâmetros Explicados:
  • type=gradle-project-kotlin: Gera o projeto utilizando Gradle com scripts em Kotlin DSL (build.gradle.kts).
  • language=kotlin: Configura a linguagem de compilação principal e os testes para Kotlin.
  • bootVersion=4.1.2: Define a versão moderna do Spring Boot.
  • jvmVersion=21: Define a versão alvo da JVM para a compilação do bytecode (suporta também jvmVersion=25 caso já utilize JDK 25).
  • dependencies=web: Adiciona o starter inicial para APIs web e controllers.

Opção B: Construção Manual Passo a Passo (build.gradle.kts Completo)

Se preferir configurar o projeto artesanalmente sem dependência do gerador externo, ou se estiver integrando a configuração a um repositório existente, siga os três passos estruturados abaixo:

Passo 1: Criar a Estrutura Canônica de Diretórios

No terminal, execute os comandos de criação de pastas:

1
2
3
4
5
6
7
8
mkdir -p test-with-spring-starter
cd test-with-spring-starter

# Cria a árvore canônica de diretórios (main e test)
mkdir -p src/main/kotlin/com/testwithspring/starter
mkdir -p src/main/resources
mkdir -p src/test/kotlin/com/testwithspring/starter
mkdir -p src/test/resources

Passo 2: Configurar o settings.gradle.kts

Crie o arquivo settings.gradle.kts na raiz do projeto:

1
rootProject.name = "test-with-spring-starter"

Passo 3: Configurar o build.gradle.kts

Crie o arquivo build.gradle.kts na raiz do projeto com a declaração exata de plugins, toolchain JVM, repositórios, dependências e a ativação explícita da plataforma de testes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
plugins {
    kotlin("jvm") version "2.4.21"
    kotlin("plugin.spring") version "2.4.21"
    id("org.springframework.boot") version "4.1.2"
    id("io.spring.dependency-management") version "1.1.7"
}

group = "com.testwithspring.starter"
version = "0.0.1-SNAPSHOT"

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(21)) // Altere para 25 caso utilize JDK 25
    }
}

repositories {
    mavenCentral()
}

dependencies {
    // Spring Boot Base
    implementation("org.springframework.boot:spring-boot-starter")
    implementation("org.jetbrains.kotlin:kotlin-reflect")

    // Starters e Ferramentas Essenciais de Testes
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testImplementation("org.junit.jupiter:junit-jupiter:6.0.0")
    testImplementation("org.assertj:assertj-core:3.27.3")
    testImplementation("io.mockk:mockk:1.14.0")
}

tasks.withType<Test> {
    // Habilita o motor JUnit Platform para execução de testes Jupiter
    useJUnitPlatform()

    // Configura saída descritiva no terminal para cada teste executado
    testLogging {
        events("passed", "skipped", "failed")
        showExceptions = true
        showCauses = true
        showStackTraces = true
    }
}

kotlin {
    jvmToolchain(21)
}
Por que useJUnitPlatform() é obrigatório? Por padrão histórico, o Gradle executava testes utilizando o runner clássico do JUnit 4. A instrução useJUnitPlatform() orienta a task test do Gradle a carregar o JUnit Platform Launcher, permitindo que o junit-jupiter-engine (JUnit Jupiter 6) descubra e execute todas as classes anotadas com @Test.

Passo 4: Criando um Teste de Sanidade (Smoke Test)

Para verificar na prática que o compilador Kotlin, o Gradle, o motor do JUnit Jupiter, o AssertJ e o MockK estão sincronizados no classpath sem conflitos de dependências, crie o arquivo src/test/kotlin/com/testwithspring/starter/SmokeTest.kt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.testwithspring.starter

import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test

@DisplayName("Verificação de Sanidade do Ambiente de Testes")
class SmokeTest {

    interface ServicoDeVerificacao {
        fun obterStatus(): String
    }

    @Test
    @DisplayName("Deve validar a integração do JUnit Jupiter 6, AssertJ e MockK")
    fun `deve verificar que todo o ecossistema de testes esta operacional`() {
        // 1. Validando o MockK
        val servicoMock = mockk<ServicoDeVerificacao>()
        every { servicoMock.obterStatus() } returns "AMBIENTE_OPERACIONAL"

        val resultado = servicoMock.obterStatus()

        // 2. Validando o AssertJ Core
        assertThat(resultado)
            .`as`("Status retornado pelo MockK validado com asserções AssertJ")
            .isNotNull()
            .isEqualTo("AMBIENTE_OPERACIONAL")

        // 3. Verificando as interações com o mock
        verify(exactly = 1) { servicoMock.obterStatus() }
    }
}

Comandos de Execução e Verificação do Ambiente

Com a estrutura e o teste de sanidade definidos, execute o comando a seguir no terminal para compilar e rodar a suíte de testes:

1
./gradlew test

Caso deseje forçar a reexecução ignorando os caches do Gradle ou inspecionar o log detalhado de execução, utilize:

1
./gradlew test --rerun-tasks --info

Saída Esperada no Terminal

Quando a configuração estiver correta, você obterá uma saída limpa e descritiva semelhante a esta:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
> Task :compileKotlin UP-TO-DATE
> Task :compileJava NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :compileTestKotlin
> Task :compileTestJava NO-SOURCE
> Task :processTestResources NO-SOURCE
> Task :testClasses
> Task :test

SmokeTest > Deve validar a integração do JUnit Jupiter 6, AssertJ e MockK PASSED

BUILD SUCCESSFUL in 2s
3 actionable tasks: 2 executed, 1 up-to-date

Relatório Visual em HTML

Ao concluir a execução da task test, o Gradle gera automaticamente um relatório navegável em HTML. Você pode abri-lo diretamente no seu navegador padrão:

1
2
3
4
5
6
7
8
# No Linux:
xdg-open build/reports/tests/test/index.html

# No macOS:
open build/reports/tests/test/index.html

# No Windows (PowerShell):
Start-Process build/reports/tests/test/index.html

Esse relatório detalha a taxa de sucesso global da suíte, a contagem de testes executados, a duração de cada teste em milissegundos e eventuais stack traces de exceções.


Fluxo de Execução da Arquitetura

O diagrama abaixo ilustra como o terminal e a ferramenta de build interagem com o motor do JUnit Platform e as bibliotecas do ecossistema:

flowchart TD DEV["Desenvolvedor / Terminal
./gradlew test"] --> GRADLE["Gradle Test Runner
(Task :test)"] GRADLE --> PLATFORM["JUnit Platform Launcher
(useJUnitPlatform)"] PLATFORM --> ENGINE["JUnit Jupiter 6 Test Engine"] ENGINE --> TEST["SmokeTest.kt
@Test / @DisplayName"] TEST --> MOCKK["MockK
(Mocks & Spies)"] TEST --> ASSERTJ["AssertJ Core
(Fluent Assertions)"] TEST --> REPORT["build/reports/tests/test/index.html
BUILD SUCCESSFUL"]

Com o projeto devidamente configurado e operacional, você tem a base necessária para avançar com confiança pelas aulas seguintes, explorando em profundidade o ciclo de vida, as anotações e os recursos modernos do JUnit Jupiter 6!

Conteúdo