Java Unit Testing Com Spring Boot 3, Junit 5 e Mockito: Theory
Java Unit Testing Com Spring Boot 3, Junit 5 e Mockito: Theory
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
O que são Testes Unitários?
Um teste unitário é um pequeno método que você escreve para testar
alguma parte do seu código.
Parâmetros Resultados
// Code under test Teste Unitário
Parâmetros Resultados
Teste Unitário
}
Classe Classe
Teste Unitário Teste Unitário
Classe Classe
Teste Unitário Teste Unitário
@Test
void testSum_WhenSixDotTwoIsAddedByTwo_ShouldReturnEightDotTwo() {
// Given / Arrange
SimpleMath math = new SimpleMath();
// When / Act
Double actual = math.sum(6.2D, 2D);
// Then / Assert
assertEquals(8.2D, actual, () -> "6.2 + 2 did not produce 8.2!");
}
Test Reports
Classe Classe
Teste Unitário Teste Unitário
Classe Classe
Teste Unitário Teste Unitário
Teste Unitário
HTTP Client
Dependency Teste Unitário
Teste Unitário
Classe
• Resposta inválida do
Teste Unitário
HTTP Client
HTTP Client
Dependency Teste Unitário • N outras validações ...
Teste Unitário
0204 Por que escrever Testes Unitários?
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
Por que escrever Testes Unitários?
• Ter certeza de que o código funciona;
• O código funciona tanto com parâmetros válidos quanto
inválidos ;
• O código funciona hoje e vai continuar funcionando no
futuro;
• O código continuará funcionando inclusive depois que
fizermos mudanças.
0205 O Princípio F.I.R.S.T.
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
O Princípio F.I.R.S.T.
Fast – os testes unitários devem executar rapidamente;
Independent – os testes unitários devem ser
independentes uns dos outros;
Repeatable – os testes unitários devem ser repetíveis;
Self-validating – os testes unitários devem se auto
validarem;
Thorough & Timely – os testes unitários devem cobrir
casos extremos.
O Princípio F.I.R.S.T.
Fast
Independent
Repeatable
Self-validating
Thorough & Timely
0206 Testando Código em Isolamento
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
Testando Código em Isolamento
Classe A Classe B
Método C
Teste Unitário Método A
Método D
Método B
Método E
Testando Código em Isolamento
Classe A Classe B
Método C
Teste Unitário Método A
Método D
Método B
Método E
Injeção de Dependências
Objeto A
Objeto B Objeto C
Mock Mock
Objeto B Objeto C Objeto B Objeto C
Objeto A Objeto A
Injeção de Dependências
Objeto A
Objeto B Objeto C
Mock Stub
Objeto A Objeto B
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
A Pirâmide de Testes
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
O que é JUnit 5
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
• JUnit Platform – A plataforma JUnit é o principal
framework para testes na JVM, sendo a base que
fundamenta a maioria das novas ferramentas de testes;
• JUnit Jupiter – É a combinação do novo modelo de
programação e extensão para escrever testes e extensões
para o JUnit 5;
• JUnit Vintage – TestEngine de backward compatibility para
a execução de testes escritos em JUnit 3 e JUnit 4.
0209 JUnit e Ferramentas de Build
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
JUnit e Ferramentas de Build
• IDE’s: • Ferramentas de Build:
– Spring Tool Suite; – Maven;
– Eclipse; – Gradle;
– IntelliJ IDEA; – Ant;
– NetBeans; – etc.
– Visual Studio Code
– etc.
0317 Ciclo de Vida dos Testes no JUnit 5
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
Ciclo de Vida dos Testes no JUnit 5
@AfterAll
4 cleanup()
0411 Introdução ao Ciclo de Vida do Test Instance
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
Ciclo de Vida dos Testes no JUnit 5
• Por padrão, o ciclo de vida da instância de testes é "por método“;
• A ordem de execução é determinística, mas intencionalmente não óbvia.
Test Method 1
Test Method 3
Ciclo de Vida dos Testes no JUnit 5
@TestInstance(Lifecycle.PER_CLASS)
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
Ciclo de Vida dos Testes no JUnit 5
1002 Conhecendo a Annotation @DataJpaTest do Spring Boot
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
Testando a Camada de Repositórios de
uma Aplicação Spring Boot
Controller Repository
Service Layer
Layer Layer
@DataJpaTest
@DataJpaTest annotation
• O Spring Boot fornece a anotação @DataJpaTest para testar os componentes da
camada de persistência, que configurarão automaticamente um banco de
dados embarcado em memória para fins de teste;
• A anotação @DataJpaTest não carrega outros beans do Spring (@Components,
@Controller, @Service e beans anotados) no ApplicationContext;
• Por padrão, ele procura por classes @Entity e configura os repositórios do
Spring Data JPA anotados com a anotação @Repository;
• Por padrão, os testes anotados com @DataJpaTest são transacionais e são
revertidos ao final de cada teste;
• Para testar repositórios do Spring Data JPA ou qualquer outro componente
relacionado ao JPA, o Spring Boot fornece a anotação @DataJpaTest.
1102 Overview e as Annotations @Mock e @InjectMocks do
Mockito
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
Testando a Camada de Serviços de
uma Aplicação Spring Boot
Controller Repository
Service Layer
Layer Layer
@Mock e
@InjectMocks
Mockito @InjectMocks Annotation
• Quando queremos injetar um objeto mockado em outro objeto mockado,
podemos usar a annotation @InjectMocks. A annotation @InjectMocks cria um
mock da classe e injeta os mocks que estão marcados com as annotations
@Mock nela.
@ExtendWith(MockitoExtension.class)
public class PersonServicesTest {
@Mock
private PersonRepository repository;
@InjectMocks
private PersonServices service;
1202 Overview do Teste de Controller e a Annotation
@WebMvcTest
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
Testando a Camada de Controllers de
uma Aplicação Spring Boot
Controller Repository
Service Layer
Layer Layer
@WebMvcTest
JsonPath Library
• Uma DSL Java para leitura de documentos JSON.
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
@WebMvcTest Annotation
• O Spring Boot fornece a anotação @WebMvcTest para testar controllers Spring MVC.
Além disso, os testes baseados em @WebMvcTest são mais rápidos, pois carregam
apenas o controller especificado e suas dependências, sem carregar a aplicação
inteira;
• O Spring Boot instancia apenas a camada web em vez de todo o application context.
Em uma aplicação com vários controllers, você pode definir a instanciação de apenas
um deles usando, por exemplo, @WebMvcTest(PersonController.class).
@WebMvcTest
PersonContoller
BookController
...
Controller Repository
AnyController Service Layer
Layer Layer
@WebMvcTest x @SpringBootTest
• O Spring Boot fornece a anotação @WebMvcTest para testar controllers do
Spring MVC. Essa anotação cria um application context que contém todos os
beans necessários para testar um controlador web do Spring;
• O Spring Boot fornece a anotação @SpringBootTest para testes de integração.
Essa anotação carrega um application context completo;
• Teste de unidade - anotação @WebMvcTest;
• Teste de integração - anotação @SpringBootTest.
PersonContoller
BookController
...
Controller Repository
AnyController Service Layer
Layer Layer
1302 Integration Testing e @SpringBootTest Annotation Overview
Leandro Costa
https://www.erudio.com.br/ https://www.youtube.com/c/ErudioTraining
https://www.semeru.com.br/ https://hub.docker.com/u/leandrocgsi/
https://github.com/leandrocgsi/automated-tests-with-java-erudio
Testes de Integração em uma
Aplicação Spring Boot
• Como o nome sugere, os testes de integração têm foco na integração de
diferentes camadas da aplicação. Isso também significa que não há uso de
mocks;
Controller Repository
Service Layer
Layer Layer
Testes de Integração em uma
Aplicação Spring Boot
@SpringBootTest
Controller Repository
Service Layer
Layer Layer
Testes de Integração em uma
Aplicação Spring Boot
Controller Repository
Service Layer
Layer Layer
Testes de Integração em uma
Aplicação Spring Boot
Controller Repository
Service Layer
Layer Layer
Testes de Integração em uma
Aplicação Spring Boot
Controller Repository
Service Layer
Layer Layer
@SpringBootTest
• O Spring Boot fornece a anotação @SpringBootTest para testes de integração.
Essa anotação cria um application context completo.
Controller Repository
Service Layer
Layer Layer
@SpringBootTest
• Ele inicializa um servidor embarcado, cria um web environment e possibilita
que os métodos @Test façam testes de integração.
• Por padrão, @SpringBootTest não inicia um servidor. Precisamos adicionar o
atributo WebEnvironment para refinar ainda mais como nossos testes serão
executados. Existem várias opções:
• MOCK (Padrão): Carrega um WebServerApplicationContext e fornece um web environment mockado;
• RANDOM_PORT: Carrega um WebServerApplicationContext e fornece um web environment real. O
servidor embarcado é iniciado e exposto em uma porta aleatória. Essa opção deve ser usada para
testes de integração;
• DEFINED_PORT: Carrega um WebServerApplicationContext e fornece um web environment real;
• NONE: Carrega um ApplicationContext usando o SpringApplication, mas não fornece nenhum web
environment.