Verificando Invocações e Slots no MockK
Ao concluirmos esta aula, compreenderemos como podemos verificar as interações que aconteceram entre o sistema sob teste (SUT) e um mock utilizando MockK 1.14, Kotlin 2.4.21 e JUnit Jupiter 6.0.3.
Este webinar assume que:
Obtenha o código-fonte no GitHub
Introdução ao Sistema Sob Teste (SUT)
Durante esta aula, verificaremos as interações que aconteceram entre o sistema sob teste e um mock de TaskRepository. A interface TaskRepository declara as funções que fornecem operações CRUD para objetos Task.
Como o objetivo é manter tudo o mais simples e direto possível, adicionamos as declarações dos componentes do nosso modelo de dados em um único arquivo de código-fonte chamado Task.kt. Esse arquivo tem a seguinte estrutura:
|
|
A interface TaskRepository possui três funções:
- A função
findById()retorna as informações de uma tarefa utilizando o seuidcomo critério de busca. Se nenhuma tarefa for encontrada no banco de dados, esta função retornanull. - A função
findByCreatorAndStatus()retorna todas as tarefas que foram criadas pela pessoa especificada e que possuem o status informado. Se nenhuma tarefa for encontrada no banco de dados, esta função retorna uma lista vazia. - A função
create()insere uma nova tarefa no banco de dados e retorna as informações da tarefa criada.
O código-fonte da interface TaskRepository é o seguinte:
|
|
A seguir, aprenderemos a verificar invocações de função com o MockK.
Verificando Invocações de Função com o MockK
Quando precisamos verificar as interações que aconteceram entre o sistema sob teste e um mock no MockK 1.14, podemos utilizar as seguintes funções:
- A função
verify()nos permite verificar que o sistema sob teste invocou a função especificadaXvezes utilizando os parâmetros de função esperados. Podemos especificar o número esperado de invocações de função utilizando estes parâmetros:- O parâmetro
atLeastnos permite verificar que a função especificada foi invocada pelo menosXvezes. - O parâmetro
atMostnos ajuda a garantir que a função especificada foi invocada no máximoXvezes. - O parâmetro
exactlynos permite especificar o número exato de invocações esperadas da função.
- O parâmetro
- A função
confirmVerified()nos ajuda a garantir que a nossa função de teste verifique todas as interações ocorridas entre o sistema sob teste e os objetos mock especificados. Esta função é tipicamente utilizada em conjunto com a funçãoverify(). - A função
verifyAll()verifica todas as invocações de função especificadas. Esta função ignora a ordem das invocações de função. - A função
verifyOrder()garante que as invocações de função especificadas aconteceram na ordem esperada. - A função
verifySequence()verifica que as invocações de função especificadas aconteceram na ordem esperada e garante que não houve nenhuma outra interação entre o sistema sob teste e o nosso mock.
Leitura Adicional:
Vamos analisar oito exemplos que demonstram como podemos verificar as interações que aconteceram entre o sistema sob teste e um mock.
Exemplo 1: Verificando que uma Função Não Foi Invocada
Se precisarmos verificar que uma função não foi invocada com os parâmetros especificados, devemos utilizar a função verify(). Quando invocamos esta função, precisamos especificar o número esperado de invocações configurando o valor do parâmetro exactly para 0. Além disso, devemos especificar a invocação de função que não deveria ter acontecido.
Vamos verificar que a função create() da interface TaskRepository não foi invocada. Depois de especificarmos a nossa expectativa, o código-fonte da nossa função de teste fica da seguinte forma:
|
|
Exemplo 2: Verificando que uma Função Foi Invocada Uma Vez
Se precisarmos verificar que uma função foi invocada uma única vez utilizando os parâmetros de função especificados, devemos usar a função verify(). Quando invocamos esta função, precisamos especificar o número esperado de invocações definindo o valor do parâmetro exactly como 1. Também devemos especificar a função invocada e os parâmetros esperados.
Vamos verificar que a função findById() da interface TaskRepository foi invocada uma vez utilizando o parâmetro de função 1L. Depois de especificarmos a nossa expectativa, o código-fonte da nossa função de teste fica assim:
|
|
Exemplo 3: Verificando que Não Existem Invocações de Função Não Verificadas
Se precisarmos verificar que não restaram invocações de função não verificadas, devemos utilizar a função confirmVerified(). Ao invocarmos esta função, devemos passar os objetos mock inspecionados como argumento da função.
Vamos garantir que a nossa função de teste invocou apenas a função findById() da interface TaskRepository utilizando o parâmetro de função 1L. Após especificarmos a nossa expectativa, o código-fonte da nossa função de teste fica da seguinte forma:
|
|
Exemplo 4: Verificando que Apenas as Invocações de Função Especificadas Aconteceram em Qualquer Ordem
Se precisarmos verificar que apenas as invocações de função especificadas aconteceram, independentemente da ordem em que foram chamadas, devemos especificar as invocações de função esperadas utilizando a função verifyAll().
Vamos verificar que a nossa função de teste invocou a função findById() duas vezes utilizando os parâmetros de função 1L e 5L. Depois de especificarmos a nossa expectativa, o código-fonte da nossa função de teste fica da seguinte maneira:
|
|
Exemplo 5: Verificando que Apenas as Invocações de Função Especificadas Aconteceram na Ordem Informada
Se precisarmos verificar que apenas as invocações de função especificadas aconteceram exatamente na ordem informada (sem nenhuma outra interação adicional), devemos especificar as invocações esperadas utilizando a função verifySequence().
Vamos verificar que a nossa função de teste invocou a função findById() três vezes utilizando os parâmetros de função 5L, 1L e 99L. Após especificarmos a nossa expectativa, o código-fonte da nossa função de teste fica assim:
|
|
Exemplo 6: Verificando que as Invocações de Função Especificadas Aconteceram na Ordem Informada
Se precisarmos verificar que determinadas invocações de função aconteceram na ordem informada (permitindo que outras invocações tenham ocorrido entre elas), devemos especificar as invocações esperadas utilizando a função verifyOrder().
Vamos verificar que a nossa função de teste invocou a função findById() duas vezes na ordem esperada utilizando os parâmetros de função 5L e 99L. Depois de especificarmos a nossa expectativa, o código-fonte da nossa função de teste fica da seguinte forma:
|
|
Exemplo 7: Utilizando Argument Matchers Simples
Se quisermos especificar os parâmetros de função esperados utilizando argument matchers simples, podemos empregar esses matchers diretamente quando declararmos a invocação de função esperada dentro do bloco de verificação.
Por exemplo, vamos verificar que a nossa função de teste invocou a função findByCreatorAndStatus() da interface TaskRepository uma vez utilizando como parâmetros de função: qualquer objeto Long (any()) e TaskStatus.OPEN.
Depois de especificarmos a nossa expectativa, o código-fonte da nossa função de teste fica da seguinte forma:
|
|
Exemplo 8: Especificando o Parâmetro de Função Esperado com um Predicado
Se quisermos especificar o parâmetro de função esperado utilizando um predicado, devemos definir o predicado por meio da função match() ao declararmos a invocação de função esperada.
Vamos verificar que a nossa função de teste invocou a função create() da interface TaskRepository uma única vez e garantir que a propriedade id do objeto Task passado como parâmetro de função seja igual a 1L.
Depois de especificarmos a nossa expectativa, o código-fonte da nossa função de teste fica da seguinte maneira:
|
|
Agora já sabemos como verificar as interações que aconteceram entre o sistema sob teste e um mock. Vamos resumir o que aprendemos nesta aula.
Resumo
Esta aula nos ensinou cinco coisas fundamentais:
- A função
verify()nos permite verificar que o sistema sob teste invocou a função especificadaXvezes utilizando os parâmetros de função esperados. - A função
confirmVerified()nos ajuda a garantir que a nossa função de teste verifique todas as interações entre o sistema sob teste e os objetos mock especificados. - A função
verifyAll()verifica todas as invocações de função especificadas e ignora a ordem das invocações de função. - A função
verifyOrder()garante que as invocações de função especificadas aconteceram na ordem esperada. - A função
verifySequence()verifica que as invocações de função especificadas aconteceram na ordem esperada e garante que não houve nenhuma outra interação entre o sistema sob teste e o nosso mock.