Especificando Controladores Web com Kotest: Renderização de Dados
Depois de concluirmos esta aula, nós:
- Saberemos como criar especificações no Kotest 6 para controladores web tradicionais do Spring MVC que buscam dados e renderizam uma view.
- Compreenderemos como documentar o sistema sob especificação de forma executável usando os blocos
Given,When,TheneAnd.
1. Conhecendo o Sistema Sob Especificação
Precisamos especificar o comportamento esperado do método handler que processa requisições HTTP GET enviadas para o caminho /task/{taskId}. O nome desse método é showTask(), e ele executa três passos:
- Busca a tarefa no banco de dados invocando o método
findById(taskId)da interfaceTaskCrudService. - Adiciona a tarefa encontrada a um atributo do
Modelchamado"task". - Retorna o nome da view (
"task/view") que renderiza os detalhes da tarefa encontrada.
Veja o código-fonte do nosso controlador TaskCrudController:
|
|
A classe TaskDTO é um DTO que contém os dados completos de uma tarefa:
|
|
Onde PersonDTO e TagDTO são objetos simples:
|
|
Vamos construir passo a passo a nossa especificação para o método showTask().
2. Especificando o Comportamento Esperado
Podemos especificar o comportamento do método showTask() na classe TaskCrudControllerSpec seguindo três etapas:
Passo 1: Estrutura Inicial da Especificação
Primeiro, configuramos o MockMvc em modo standalone (como aprendemos na aula anterior), declaramos as constantes CREATION_TIME e MODIFICATION_TIME e abrimos o contexto da funcionalidade "Show task":
|
|
Passo 2: Especificando o Cenário em que a Tarefa Não É Encontrada (404)
Precisamos verificar que o método showTask() se comporta corretamente quando a tarefa solicitada não existe:
- Garantimos que o mock
TaskCrudServicelance umaNotFoundExceptionquandofindById(99L)for invocado. - Enviamos uma requisição
GET /task/99e guardamos o objetoResultActionsretornado na variávelresponse. - Verificamos que o controlador retorna o código de status HTTP
404 Not Found. - Garantimos que o controlador renderiza a view de erro
"error/404".
|
|
Passo 3: Especificando o Cenário em que a Tarefa É Encontrada (200 OK)
Agora verificamos que o método showTask() funciona como esperado quando a tarefa solicitada é encontrada:
- Configuramos o mock
TaskCrudServicepara retornar uma tarefa fechada (TaskStatus.CLOSED,TaskResolution.DONE) contendo uma tag quandofindById(1L)for invocado (construída com oTaskDTOBuilder). - Enviamos uma requisição
GET /task/1e armazenamos oResultActionsemresponse. - Verificamos que o controlador retorna o status HTTP
200 OK. - Garantimos que o controlador renderiza a view
"task/view". - Verificamos que o atributo
"task"doModelexibe todas as informações da tarefa encontrada. - Garantimos que o atributo
"task"possui exatamente 1 tag. - Verificamos que a tag exibida possui o
id = 33Lename = "testing".
Veja como fica a classe TaskCrudControllerSpec completa:
|
|
[!NOTE] Observe três benefícios diretos dessa estrutura no Kotest:
- Utilizamos o Test Data Builder
TaskDTOBuildercombinado com argumentos nomeados do Kotlin (PersonDTO(userId = 44L, name = "Anne Assignee")), mantendo a criação de dados limpa e expressiva.- Dividimos o bloco
Thenem seções lógicas usandoAnd("..."), onde cada seção valida uma única responsabilidade (status HTTP, nome da view, atributos da tarefa, tamanho da lista de tags e conteúdo da tag).- Com descrições claras nos blocos
Given,When,TheneAnd, nossa classe de teste se torna uma especificação executável que documenta o comportamento do controlador!
Resumo
Nesta aula, aprendemos três pontos essenciais:
- Especificamos diferentes cenários de um controlador web estruturando blocos
Given,WheneThenno Kotest. - Quando uma verificação possui múltiplas responsabilidades (status HTTP, view e atributos do
Model), dividimos o blocoThenem seções específicas usandoAnd. - Boas descrições nos blocos transformam nossos testes unitários em documentação viva do sistema sob especificação.