xUnit.net - Parte 2: Testando Minimal APIs
Introdução
Com o lançamento do .NET 6, a Microsoft introduziu as Minimal APIs, uma forma simplificada e leve de criar APIs RESTful usando menos código e sem a necessidade de classes de controlador. Esta abordagem facilita o desenvolvimento rápido de serviços HTTP e é ideal para microsserviços, APIs simples ou aplicações que não necessitam da estrutura completa do ASP.NET Core MVC.
Neste guia, daremos continuidade ao estudo do xUnit.net, focando agora em como testar Minimal APIs. Exploraremos como configurar testes para endpoints HTTP, utilizar o WebApplicationFactory para hospedar a aplicação em memória durante os testes, e escrever testes que verificam o comportamento da API.
O que são Minimal APIs?
As Minimal APIs permitem que você crie endpoints HTTP diretamente no método Program.cs
, sem a necessidade de classes de controlador ou ações separadas. Elas utilizam os mesmos fundamentos do ASP.NET Core, mas com uma sintaxe mais concisa.
Exemplo de uma Minimal API:
Neste exemplo, o endpoint /hello
retorna a string "Hello World!".
Configurando o Ambiente de Testes
Pré-requisitos
SDK do .NET 6 ou superior: Certifique-se de ter o SDK do .NET 6 instalado.
IDE: Visual Studio 2022, Visual Studio Code ou outro editor de sua preferência.
Estrutura do Projeto
Vamos criar uma solução com dois projetos:
Projeto da API: Contém a Minimal API.
Projeto de Testes: Contém os testes unitários usando xUnit.net.
Passo 1: Criar a Solução e o Projeto da API
Passo 2: Criar o Projeto de Testes
Configurando o Projeto da API
Para o propósito deste guia, criaremos uma Minimal API simples que expõe endpoints para manipular um recurso de "Produtos".
Definindo o Modelo
Configurando os Endpoints
No Program.cs
, vamos adicionar endpoints para CRUD básico.
Testando a Minimal API com xUnit.net
Para testar a Minimal API, precisamos hospedar a aplicação em um servidor de teste em memória. O Microsoft.AspNetCore.Mvc.Testing fornece a classe WebApplicationFactory<TEntryPoint>
que facilita esse processo.
Passo 1: Instalar Pacotes Necessários
No projeto de testes, instale o pacote Microsoft.AspNetCore.Mvc.Testing:
Passo 2: Criar a Classe de Teste
Explicando o Código de Teste
Classe ProductApiTests
Implementa
IClassFixture<WebApplicationFactory<Program>>
, que fornece uma instância deHttpClient
configurada para testar a aplicação.O
WebApplicationFactory<TEntryPoint>
hospeda a aplicação em memória para testes.
Métodos de Teste
GetProducts_ReturnsListOfProducts
Objetivo: Verificar se o endpoint
/products
retorna uma lista de produtos.Passos:
Faz uma requisição GET para
/products
.Verifica se a resposta tem status de sucesso.
Lê o conteúdo da resposta como uma coleção de
Product
.Verifica se a coleção não é nula e não está vazia.
GetProductById_ReturnsProduct_WhenProductExists
Objetivo: Verificar se o endpoint
/products/{id}
retorna um produto existente.Passos:
Define um
productId
existente.Faz uma requisição GET para
/products/{productId}
.Verifica se a resposta tem status de sucesso.
Lê o conteúdo da resposta como um
Product
.Verifica se o produto não é nulo e se o
Id
corresponde.
GetProductById_ReturnsNotFound_WhenProductDoesNotExist
Objetivo: Verificar se o endpoint
/products/{id}
retorna 404 quando o produto não existe.Passos:
Define um
productId
que não existe.Faz uma requisição GET para
/products/{productId}
.Verifica se a resposta tem status 404 Not Found.
CreateProduct_ReturnsCreatedProduct
Objetivo: Verificar se é possível criar um novo produto.
Passos:
Define um novo produto.
Faz uma requisição POST para
/products
com o produto no corpo.Verifica se a resposta tem status 201 Created.
Lê o conteúdo da resposta como um
Product
.Verifica se os dados do produto criado correspondem aos enviados.
UpdateProduct_ReturnsNoContent_WhenProductExists
Objetivo: Verificar se é possível atualizar um produto existente.
Passos:
Define um
productId
existente e um produto atualizado.Faz uma requisição PUT para
/products/{productId}
com o produto atualizado.Verifica se a resposta tem status 204 No Content.
DeleteProduct_ReturnsNoContent_WhenProductExists
Objetivo: Verificar se é possível deletar um produto existente.
Passos:
Define um
productId
existente.Faz uma requisição DELETE para
/products/{productId}
.Verifica se a resposta tem status 204 No Content.
Executando os Testes
Para executar os testes, utilize o comando:
Saída Esperada:
Personalizando o WebApplicationFactory
Em alguns casos, você pode precisar personalizar a configuração da aplicação durante os testes, por exemplo, para usar um banco de dados em memória ou substituir serviços.
Criando uma Subclasse de WebApplicationFactory
Usando a Classe Personalizada nos Testes
Dicas e Boas Práticas
Isolamento dos Testes
Certifique-se de que cada teste é independente dos outros.
Se os dados usados nos testes são compartilhados (como a lista de produtos em memória), isso pode causar interferência entre os testes.
Considere redefinir o estado antes de cada teste ou usar escopos de serviço para criar instâncias separadas.
Uso de Banco de Dados em Memória
Para testar interações com o banco de dados, você pode usar um banco de dados em memória como o SQLite in-memory ou o InMemoryDatabase do Entity Framework Core.
Exemplo com Entity Framework Core:
Testes Assíncronos
Use os métodos assíncronos do
HttpClient
exUnit
para garantir que os testes não bloqueiem o thread.
Verificação de Conteúdo
Além de verificar o status da resposta, verifique o conteúdo para garantir que a API está retornando os dados corretos.
Use
Assert.Equal
para comparar valores esperados e reais.
Testando Erros e Exceções
Para garantir que sua API lida corretamente com erros, escreva testes que simulem condições de erro.
Exemplo:
Mockando Serviços Externos
Se sua Minimal API depende de serviços externos, você pode usar mocks para isolar os testes.
Exemplo:
Suponha que sua API use um serviço de envio de e-mails.
Crie uma interface
IEmailService
e uma implementação de mock para os testes.No
CustomWebApplicationFactory
, substitua o serviço real pelo mock.
Testando Autenticação e Autorização
Se sua API usa autenticação e autorização, você precisa configurar o contexto de segurança nos testes.
Simulando um Usuário Autenticado
Use middleware personalizado ou configure o
HttpClient
para incluir tokens de autenticação.
Exemplo:
Configurando Serviços de Autenticação
No
CustomWebApplicationFactory
, configure serviços de autenticação para os testes.
Recursos Adicionais
Documentação Oficial do xUnit.net: https://xunit.net/
Testes de Integração no ASP.NET Core: Microsoft Docs
Minimal APIs Overview: Microsoft Docs
Exercícios Práticos
Adicionar Validações à API:
Implemente validações nos endpoints, como verificar se o nome do produto não é nulo.
Escreva testes para verificar se a API retorna erros adequados quando as validações falham.
Testar Paginação e Filtros:
Adicione suporte a paginação e filtros nos endpoints.
Escreva testes que verifiquem se a paginação e os filtros funcionam corretamente.
Implementar Testes de Performance:
Use ferramentas como o BenchmarkDotNet para medir o desempenho de sua API.
Analise os resultados e otimize o código conforme necessário.
Conclusão
Testar Minimal APIs com xUnit.net é um processo direto que utiliza as mesmas ferramentas e conceitos dos testes em aplicações ASP.NET Core convencionais. Ao hospedar a aplicação em memória usando o WebApplicationFactory
, podemos escrever testes que verificam os endpoints HTTP de forma eficaz.
Neste guia, cobrimos:
Como configurar o ambiente de testes para Minimal APIs.
Escrever testes para endpoints GET, POST, PUT e DELETE.
Personalizar o
WebApplicationFactory
para cenários avançados.Boas práticas para garantir a confiabilidade e a manutenção dos testes.
A incorporação de testes automatizados em seu fluxo de desenvolvimento melhora a qualidade do software e facilita a detecção precoce de bugs e regressões.
Observações Finais
Atualização Contínua: Mantenha seus testes atualizados conforme a API evolui.
Cobertura de Testes: Busque uma cobertura abrangente, incluindo cenários de erro e validações.
Colaboração: Compartilhe conhecimento com sua equipe e incentive a cultura de testes.
Espero que este guia tenha expandido seu conhecimento sobre testes com xUnit.net e que você esteja mais preparado para testar Minimal APIs em seus projetos!