Executando Verificação de Contratos com JUnit 6
Ao concluirmos este webinar, seremos capazes de:
- Criar e configurar um projeto Gradle (Kotlin DSL) que utiliza o Spring Cloud Contract 5.0 e o JUnit Jupiter 6.0.3.
- Compreender como utilizar o Spring Cloud Contract em conjunto com o JUnit 6 (JUnit Platform / Jupiter) ao implementarmos serviços REST produtores (producers) e consumidores (consumers) em Kotlin.
Este webinar assume que:
- Você já está familiarizado com os fundamentos do JUnit Jupiter (JUnit 5/6).
- Você sabe implementar um serviço REST produtor com Spring Cloud Contract
- Você sabe implementar um serviço REST consumidor com Spring Cloud Contract
Antes de começarmos, vale destacar o contexto histórico e a evolução da stack: quando o suporte à plataforma JUnit Jupiter foi originalmente introduzido no ecossistema Spring Cloud Contract (na época da versão
2.1.0.M2), era necessário recorrer a repositórios Milestone do Spring porque a linha estável antiga suportava apenas JUnit 4 por padrão. Na stack moderna com Spring Boot 4.1.2, Spring Cloud Contract 5.0, Kotlin 2.4.21 e Gradle 9.8.2, o suporte à plataforma JUnit Jupiter (JUnit 6.0.3) é nativo, mas ainda precisamos configurar explicitamente a DSL do plugin, a plataforma de testes do Gradle e o modo de geraçãoTestFramework.JUNIT5(identificador usado pelo gerador do Spring Cloud Contract para toda a arquitetura JUnit Jupiter 5/6).
Obtenha o código-fonte de referência no GitHub
Modificando o Serviço REST Produtor
Quando queremos utilizar o JUnit Jupiter 6 no projeto do nosso serviço REST produtor (producer), precisamos modificar o nosso arquivo de build (build.gradle.kts) e a classe base que é estendida pelas classes de teste reais geradas pelo plugin Gradle do Spring Cloud Contract.
Vamos começar modificando o nosso arquivo de build.
Modificando o Nosso Arquivo de Build (build.gradle.kts)
Podemos realizar as alterações necessárias no nosso arquivo build.gradle.kts seguindo estes passos:
Primeiro, precisamos garantir que o Gradle configure os repositórios necessários (como o mavenCentral() e, caso você esteja testando versões pré-lançamento ou milestones do ecossistema Spring Cloud, o repositório https://repo.spring.io/milestone) tanto para a resolução das dependências do nosso serviço REST produtor quanto para os plugins utilizados pelo build do Gradle.
Podemos fazer isso adicionando o seguinte trecho ao nosso arquivo settings.gradle.kts (para plugins) e build.gradle.kts (para dependências):
|
|
Segundo, precisamos definir a versão do BOM (Bill of Materials) do Spring Cloud Contract (spring-cloud-contract-dependencies) utilizado pelo nosso projeto Gradle. Isso garante que o nosso projeto utilize versões de dependências compatíveis entre si e alinhadas ao Spring Boot 4.1.2.
Podemos realizar a alteração necessária configurando o bloco dependencyManagement (ou platform) para a versão 5.0.0. Após fazermos essa alteração, a parte relevante do nosso arquivo build.gradle.kts ficará da seguinte forma:
|
|
Terceiro, precisamos declarar as dependências do JUnit Jupiter 6 no nosso arquivo build.gradle.kts. Fazemos isso adicionando as dependências junit-jupiter-api e junit-jupiter-engine (na versão 6.0.3), além do lançador da plataforma, ao bloco dependencies do nosso arquivo build.gradle.kts.
Em outras palavras, precisamos adicionar o seguinte trecho à seção dependencies do nosso arquivo de build:
|
|
Quarto, como utilizamos o JUnit Jupiter 6, precisamos garantir que o Gradle execute os nossos testes unitários e de contrato utilizando a JUnit Platform nativa na tarefa test (no Maven clássico, isso equivalia a atualizar o maven-surefire-plugin para 2.22.1+ para evitar a necessidade de configurar o antigo junit-platform-surefire-provider).
Podemos configurar a execução nativa da JUnit Platform adicionando o seguinte bloco tasks.withType<Test>() ao nosso arquivo build.gradle.kts:
|
|
Quinto, precisamos realizar as seguintes alterações na configuração do plugin do Spring Cloud Contract (org.springframework.cloud.contract no Gradle):
- Definir a versão do plugin do Spring Cloud Contract para
5.0.0no blocoplugins. - Garantir que o plugin do Spring Cloud Contract gere classes de teste que utilizem a arquitetura JUnit Jupiter (
TestFramework.JUNIT5, que gera testes anotados com@ org.junit.jupiter.api.Testcompatíveis com JUnit 5 e JUnit 6).
Após realizarmos as alterações necessárias, a configuração do plugin do Spring Cloud Contract no nosso build.gradle.kts ficará da seguinte forma:
|
|
Já realizamos todas as alterações necessárias no nosso build Gradle. A seguir, modificaremos a classe base dos nossos testes de contrato.
Modificando a Nossa Classe Base de Teste
Como nos lembramos da Parte 1, a classe base dos nossos testes de verificação de contrato configura o sistema sob teste (System Under Test) utilizando um método de preparação (setup) que é executado antes de cada método de teste gerado. É por isso que a única alteração estrutural que precisamos fazer na migração do JUnit 4 para o JUnit Jupiter 6 é substituir a antiga anotação @Before pela anotação @BeforeEach (org.junit.jupiter.api.BeforeEach).
Após realizarmos essa alteração, o código-fonte da classe BaseTest em Kotlin ficará da seguinte forma:
|
|
Concluímos as alterações necessárias no nosso serviço REST produtor. Vamos avançar e descobrir como podemos aplicar as alterações equivalentes ao nosso serviço REST consumidor.
Modificando o Serviço REST Consumidor
Quando queremos utilizar o JUnit Jupiter 6 no projeto do nosso serviço REST consumidor (consumer), precisamos modificar o nosso arquivo de build (build.gradle.kts) e as classes de teste que garantem que o sistema sob teste esteja funcionando conforme o esperado quando o contrato entre o serviço consumidor e o serviço produtor não foi alterado.
Vamos começar modificando o nosso arquivo de build.
Modificando o Nosso Arquivo de Build (build.gradle.kts)
Podemos realizar as alterações necessárias no nosso arquivo build.gradle.kts do consumidor seguindo estes passos:
Primeiro, precisamos garantir que o Gradle configure os repositórios necessários (mavenCentral() e, quando aplicável para dependências milestone do Spring, https://repo.spring.io/milestone) ao baixar as dependências do nosso serviço REST consumidor.
Podemos fazer isso adicionando o seguinte trecho ao nosso arquivo build.gradle.kts:
|
|
Segundo, precisamos definir a versão do BOM do Spring Cloud Contract que é utilizada pelo nosso projeto consumidor. Isso garante que o Stub Runner e as demais bibliotecas do projeto utilizem as versões corretas de dependências.
Podemos realizar a alteração necessária definindo a versão do BOM spring-cloud-contract-dependencies para 5.0.0. Após fazermos essa alteração, a parte relevante do nosso arquivo build.gradle.kts ficará da seguinte forma:
|
|
Terceiro, precisamos declarar as dependências do JUnit Jupiter 6 no nosso arquivo build.gradle.kts. Fazemos isso adicionando as dependências junit-jupiter-api e junit-jupiter-engine (versão 6.0.3) à seção dependencies do nosso arquivo build.gradle.kts.
Em outras palavras, precisamos adicionar o seguinte trecho à seção dependencies do nosso arquivo de build:
|
|
Quarto, como utilizamos o JUnit Jupiter 6, precisamos garantir que o Gradle execute os nossos testes utilizando o suporte nativo à JUnit Platform (assim como no Maven Surefire 2.22.1+, não precisamos configurar provedores externos manuais).
Podemos configurar a execução na tarefa test adicionando o seguinte trecho ao nosso arquivo build.gradle.kts:
|
|
Já realizamos as alterações necessárias na configuração de build do nosso projeto consumidor. A seguir, veremos como podemos modificar as nossas classes de teste.
Modificando as Nossas Classes de Teste
Como nos lembramos da Parte 2, o projeto do nosso serviço REST consumidor possui duas classes de teste. Esses testes nos ajudam a garantir que:
- O contrato fornecido pelo nosso serviço REST produtor não sofreu quebras de compatibilidade.
- O nosso serviço REST consumidor está funcionando conforme o esperado quando a tarefa (task) solicitada é encontrada.
Podemos migrar esses testes do JUnit 4 para o JUnit Jupiter 6 seguindo estes passos:
Primeiro, precisamos realizar as seguintes alterações na classe TaskContractTest:
- Utilizar a extensão
SpringExtension(@ExtendWith(SpringExtension::class)) em vez do antigo runnerSpringRunner(@RunWith(SpringRunner.class)). (Nota: no Spring Boot moderno,@SpringBootTestjá é meta-anotada com@ExtendWith(SpringExtension::class), mas declará-la explicitamente deixa evidente a transição arquitetural do modelo de Runners do JUnit 4 para o modelo de Extensions do JUnit Jupiter). - Substituir a anotação
@Beforepela anotação@BeforeEach. - Substituir a anotação
org.junit.Testpela anotaçãoorg.junit.jupiter.api.Test. - Configurar os nomes de exibição legíveis dos nossos métodos de teste utilizando a anotação
@DisplayName(ou nomes de funções com crases no Kotlin).
Após realizarmos essas alterações, o código-fonte da classe TaskContractTest ficará da seguinte forma:
|
|
Segundo, precisamos realizar as seguintes alterações na classe FindTaskByIdWhenTaskIsFoundTest:
- Utilizar a classe
SpringExtension(@ExtendWith(SpringExtension::class)) em vez da classeSpringRunner. - Substituir a anotação
org.junit.Testpela anotaçãoorg.junit.jupiter.api.Test. - Configurar os nomes de exibição dos nossos métodos de teste utilizando a anotação
@DisplayName.
Após realizarmos essas alterações, o código-fonte da nossa classe de teste ficará da seguinte forma:
|
|
Concluímos todas as alterações necessárias no projeto do nosso serviço REST consumidor. Vamos resumir o que aprendemos neste webinar.
Resumo
Este webinar nos ensinou quatro pontos essenciais:
- Precisamos alinhar a versão do BOM e do plugin do Spring Cloud Contract (
5.0.0no ecossistema Spring Boot 4.1.2; historicamente introduzido na versão2.1.0.M2) para contarmos com suporte completo à plataforma JUnit Jupiter (JUnit 5/6). - Se quisermos utilizar o JUnit Jupiter 6 ao escrevermos o nosso serviço REST produtor, precisamos alterar a configuração do plugin do Spring Cloud Contract no nosso arquivo de build. Mais especificamente, devemos definir a opção de configuração
testFrameworkcomoTestFramework.JUNIT5(que instrui o gerador de código a emitir testes baseados emorg.junit.jupiter.api.*). - Precisamos executar os nossos testes habilitando o suporte nativo à JUnit Platform na ferramenta de build (
useJUnitPlatform()no Gradle 9.8.2, equivalente ao suporte nativo do Maven Surefire2.22.1+). - Podemos migrar nossas classes base e classes de teste de consumidor do JUnit 4 para o JUnit Jupiter 6 substituindo as anotações antigas do JUnit 4 (
@RunWith,@Before,@org.junit.Test) pelas novas anotações providas pelo JUnit Jupiter (@ExtendWith(SpringExtension::class),@BeforeEach,@org.junit.jupiter.api.Teste@DisplayName).