DEV Community

Cover image for Como usar Mockito no Quarkus (feat. jUnit)
Aleatório
Aleatório

Posted on

Como usar Mockito no Quarkus (feat. jUnit)

Nos últimos tempos fiz dois posts topzeira, um falando sobre o que são testes e outro sobre como utilizar a lib do testcontainers para fazer testes de integração. No artigo de hoje, vamos utilizar a biblioteca Mockito para fazer os testes mockeados.

Esse tutorial será dividido em três partes, no primeiro vamos trabalhar com a criação de mocks e controlar o comportamento deles; no segundo vamos utilizar a biblioteca para fazer o retorno dos objetos de forma condicional; e, por fim, vamos conseguir analisar bem o objeto que estamos recebendo para ver se está tudo correto.

Para conseguir esse feito, vamos trazer o mestre do universo, o único que fica lindo de cabelo chanel e tanguinha, aquele que dá os melhores conselhos: He-man.

Image heman

O que faremos?

Nesse artigo vamos criar um o castelo de GraySkull onde as pessoas querem entrar. Esse castelo tem um porteiro que vai dizer se você entra na entrada VIP ou entrada normal.

O castelo ficará com a seguinte cara.

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

@ApplicationScoped
public class CasteloDeGraySkull {
  @Inject
  PortaoNormal portaoNormal;

  @Inject
  PortaoVip portaoVip;

  @Inject
  Porteiro porteiro;

  public void entrarNoCastelo(String nome) {
    System.out.println(nome + " está entrando no castelo");
    if(porteiro.identificarSeÉVip(nome)) {
      portaoVip.entrar(nome);
    } else {
      portaoNormal.entrar(nome);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

E cada portão tem a seguinte forma:

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class PortaoNormal {
  public void entrar(String nome) {
    System.out.println(nome + " entrou pelo portão normal");
  }
}
Enter fullscreen mode Exit fullscreen mode
import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class PortaoVip {
  public void entrar(String nome) {
    System.out.println(nome + " entrou pelo portão VIP");
  }
}
Enter fullscreen mode Exit fullscreen mode

Agora vem os problemas. Olha só o que aconteceu com o nosso porteiro.


import javax.enterprise.context.ApplicationScoped;


@ApplicationScoped
public class Porteiro {
  public boolean identificarSeÉVip(String nome) {
    throw new RuntimeException("O porteiro faltou!");
  }
}
Enter fullscreen mode Exit fullscreen mode

Isso mesmo, nós não temos a classe do porteiro. Isso pode acontecer por vários motivos. Seja por nós não sabermos as regras ainda ou por não termos implementado. Ou mesmo porque o porteiro depende de alguma aplicação externa que nem sempre vamos poder usar nos nossos testes.

E é nesse ponto que a beleza do Quarkus e dos mocks entram. Nós não precisamos ter o objeto de verdade para seguirmos nossas implementações. Primeiro vamos adicionar a dependência para o Mockito. Fazemos isso adicionando o trecho abaixo entre as tags <dependencies>do arquivo pom.xml.

    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-junit5</artifactId>
      <scope>test</scope>
    </dependency>
Enter fullscreen mode Exit fullscreen mode

Agora, vamos para a nossa classe de teste que será chamada de CasteloDeGraySkullTest.

import javax.inject.Inject;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.mockito.InjectMock;

@QuarkusTest //0
public class CasteloDeGraySkullTest {
  @Inject
  CasteloDeGraySkull castelo;

  @InjectMock //1
  Porteiro porteiroMock;

  @Test
  public void testeEntrarNoNormal() {
    castelo.entrarNoCastelo("He-man"); //2
  }

  @Test
  public void testeEntrarNoVip() {
    Mockito.when(porteiroMock.identificarSeÉVip(Mockito.anyString())).thenReturn(true); //3
    castelo.entrarNoCastelo("She-ha");//4
  }
}
Enter fullscreen mode Exit fullscreen mode

Agora vamos analisar o nosso código.

  • 0. A anotação @QuarkusTest indica que os testes usarão a injeção de dependência do Quarkus.
  • 1. Quando usamos a anotação @InjectMock, estamos dizendo que não é para injetarmos a classe verdadeira, porém uma versão mockada dela.
  • 2. Estamos fazendo o teste tendo o comportamento padrão do tipo boolean que é retornar false. Usando o comando mvn test, veremos a seguinte saída:
He-man está entrando no castelo
He-man entrou pelo portão normal
Enter fullscreen mode Exit fullscreen mode
  • 3. Estamos mudando o comportamento do nosso mock. Estamos dizendo que para qualquer string que for passada (Mockito.anyString()) para o método porteiroMock.identificarSeÉVip() deve ser retornado o valor true.
  • 4. Temos o teste com o valor alterado, rodando o teste, teremos a seguinte saída:
She-ha está entrando no castelo
She-ha entrou pelo portão VIP
Enter fullscreen mode Exit fullscreen mode

Considerações

Tentei dividir ao máximo o conteúdo para que todo mundo possa acompanhar sem maiores problemas e entender bem o que houve.
Mockito é uma biblioteca extremamente poderosa e auxilia bastante no desenvolvimento de testes rápidos e eficientes. Espero que todos gostem.

Ah, e o código de hoje pode ser encontrado no github.

E no próximo post, teremos uma participação especial:

Image description

Discussion (1)

Collapse
filiperoberto profile image
Filipe Roberto Silva

Eu acho o @QuakusTest muito lento, quanto é teste mockado, eu prefiro usar o @ExtendWith(MockitoExtension.class) que fica bem mais rápido para iniciar e executar os testes. O @QuakusTest deixo para os testes integrados, com H2