Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.

Prévia do material em texto

Introdução ao Mockito com Kotlin
O que é?
Mockito é um framework que facilita a criação de mocks - objetos falsos que substituem partes 
reais do código.
Para aprender mais sobre mocks e seu papel nos testes confira o artigo Mocks: Introdução a 
Automatização de Testes com Mock Object.
Por que é útil?
Mockito melhora o código de teste, porque torna ele mais legível. Além disso, Mockito também 
produz mensagens que facilitam rastrear erros.
Características
• Primeiramente escrito para Java, mas foi portado para Kotlin;
• Torna o código mais legível;
• Gera mensagens que facilitam rastrear erros.
Como utilizar: configuração
Configure Mockito em um projeto usando o Gradle, adicionando na sessão dependencies do arquivo
build.gradle.kts as seguintes dependências do Código 1.
testImplementation("org.mockito.kotlin:mockito-kotlin:4.0.0")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.3.1")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.3.1")
Código 1. Instalando o Mockito no Gradle
Note que você ainda precisará do JUnit para usar o Mockito.
Após isso, caso seu projeto ainda não tenha uma sessão de testes configurada, insira uma task, ainda
no arquivo build.gradle.kts, conforme o Código 2.
tasks.withType<Test> {
 useJUnitPlatform()
}
Código 2. Configuração de testes
A partir disso podemos começar a escrever os primeiros mocks com o Mockito.
Exemplo prático
Para ilustrar como criar um teste usando o Mockito criaremos um pequeno projeto com duas 
classes, conforme mostra a Figura 1. A ideia por trás desse microprojeto é simular um pagamento.
Payment representa o pagamento e PaymentGateway a comunicação entre a aplicação e a empresa 
que debita o saldo do cartão de crédito do cliente.
Código das classes
A função das classes Payment e PaymentGateway importam mais que seus códigos no contexto 
deste artigo.
Entendendo o que elas fazem podemos ter uma ideia de como elas fazem.
Sendo assim, os Códigos 3 e 4 demonstram a resposta de seus métodos em pseudocódigo.
open class PaymentGateway {
 open fun request() = "Request payment gateway"
}
Código 3. Classe PaymentGateway
class Payment(private val paymentGateway: PaymentGateway) {
 fun pay() = {
 // Calcula o valor final
 // Aplica descontos
 paymentGateway.request()
 }
}
Código 4. Classe Payment
Relação entre Payment e PaymentGateway
O objetivo desse exemplo é apresentar uma classe que contém regras de negócio, Payment, que 
depende de outra que não possui, PaymentGateway.
Uma vez que PaymentGateway pode falhar, por uma queda na internet, por exemplo, precisamos 
isolá-la ao testar Payment. Para isso criamos um mock para PaymentGateway. Assim, caso Payment
falhe isso não ocorrerá ao acaso.
Criando e validando o mock
Antes de criar um mock precisamos criar uma classe de testes , como mostra o Código 5. No 
método de teste `Succeeds to pay given a valid payment gateway` inserimos o código de teste.
internal class PaymentTest {
 @Test
 fun `Succeeds to pay given a valid payment gateway`() {
 val mock = mock<PaymentGateway> {
 on { request() } doReturn "mock implementation"
 }
 val payment = Payment(mock)
 payment.pay()
 verify(mock).request()
 }
}
Código 5. Classe de teste
Na Linha 5 criamos o mock usando o método mock do Mockito.
Na Linha 6, estamos substituindo o código real do método PaymentGateway::request() por um 
código falso. Ele vai fazer com que a string "mock implementation" seja retornada sempre que esse 
método for chamado.
A instrução on { request() } doReturn "mock implementation", na Linha 6, pode ser lida 
como "para o método request() quando ele for invocado, retorne 'mock implementation'".
A técnica de criar código falso para os mocks é chamada stubbing.
Na Linha 9 passamos o mock para o construtor de Payment.
Na Linha 10, invocamos o método Payment::pay() do Código 4. Internamente, o método 
Payment::pay() deve invocar PaymentGateway::request(), fazendo com nosso stub seja executado.
Na Linha 12 fazemos o assertion, a verificação que determina se o teste falhou ou não. Nessa 
assertion usamos Mockito::verify() para checar se o método PaymentGateway::request() foi 
invocado, como mostra a Figura 2.
Figura 2. Teste bem-sucedido 
Nesse caso, uma vez que PaymentGateway::request() foi invocado, o teste foi bem-sucedido.
Produzindo e analisando uma falha
Caso se deseje ver o teste falhar, podemos comentar a invocação de PaymentGateway::request() em 
Payment::pay(), conforme o Código 6.
class Payment(private val paymentGateway: PaymentGateway) {
 fun pay() {
 // paymentGateway.request()
 }
}
Código 6. PaymentGateway::request() em Payment comentado
Ao fazermos isso, Mockito::verify() saberá que PaymentGateway::request() em Payment não foi 
invocado, pois está comentado, e falhará o teste com uma mensagem como a apresentada 
no Código 7 e na Figura 3.
Wanted but not invoked:
paymentGateway.request();
-> at PaymentTest.Test mock(PaymentTest.kt:19)
Actually, there were zero interactions with this mock.
Código 7. Mensagem de erro gerada pelo Mockito
A mensagem nos permite rastrear o erro, uma vez que mostra onde o problema 
ocorreu, PaymentTest.kt:19", e o que o ocasionou, "Wanted but not invoked: 
paymentGateway.request();".
Final classes
Anteriormente, usamos o modificador open na classe PaymentGateway apresentado no Código 8.
open class PaymentGateway {
 …
}
Código 8. Classe PaymentGateway com o modificar open
Mockito não funciona com classes final, padrão do Kotlin, sem alguma configuração.
Se tentarmos executar novamente o teste após remover open da classe PaymentGateway 
receberemos o erro apresentado no Código 9.
Cannot mock/spy class PaymentGateway
Mockito cannot mock/spy because :
 - final class
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class PaymentGateway
Mockito cannot mock/spy because :
 - final class
Código 9. Erro exibido ao remover open de PaymentGateway
Além de usar open para contornar esse problema, podemos configurar o Mockito de forma que ele 
saiba o que fazer nessa condição.
Para isso crie uma arquivo chamado org.mockito.plugins.MockMaker na pasta 
src/test/resources/mockito-extensions com conteúdo do Código 10.
mock-maker-inline
Código 10. Configuração no arquivo org.mockito.plugins.MockMaker
A partir disso podemos remover o modificador open da classe PaymentGateway e nosso código 
continuará funcionando conforme esperado.
Conclusão
Atualmente, escrevemos mais códigos de testes do que qualquer outro em aplicações. Por este 
motivo, dominar técnicas triviais de teste como mocking e stubbing é fundamental para o 
programador. Nesse artigo você aprendeu como usar o Mockito para essa tarefa, escrevendo código 
de testes mais limpo e que produzem mensagens mais eficientes quanto a rastreabilidade de erros.
	Introdução ao Mockito com Kotlin
	O que é?
	Por que é útil?
	Características
	Como utilizar: configuração
	Exemplo prático
	Código das classes
	Relação entre Payment e PaymentGateway
	Criando e validando o mock
	Produzindo e analisando uma falha
	Final classes
	Conclusão

Mais conteúdos dessa disciplina