ASP .NET Core API - Testes de unidade : Roteiro básico - I


 Hoje vamos recordar como realizar testes de unidade em um projeto ASP .NET Core API que realiza um CRUD.

Antes de iniciar os testes precisamos ter um projeto que desejamos testar e para isso eu vou descrever de forma resumida como o projeto a ser testado pode ser criado usando a plataforma .NET.


Vamos usar o Visual Studio 2022 no ambiente do .NET 6.0.

Criando o projeto para testar

Vamos iniciar criando um projeto simples para podermos testar. Vamos criar um projeto Web API no Visual Studio Code para gerenciar informações de livros que iremos chamar de ApiLivraria:

Esta API possui os seguintes endpoints:

GET /Livros Retorna todos os livros
GET /Livros/{id} Obtêm um livro pelo id
POST /Livros Adiciona um novo livro
PUT /Livros/{id} Atualiza um livro existente      
DELETE /Livros/{id}     Deleta um livro

A seguir veremos o roteiro usado para criar o projeto Web API no VS Code:

1- Criar o projeto:

dotnet new webapi -o ApiLivraria

2- Abrir o projeto no VS Code :  code .

3- Criar a pasta Models no projeto e nesta pasta criar as classes:

I- Livro - Representa o modelo de domínio

public class Livro
{
    public Guid Id { get; set; }
    [Required]
    public string? Titulo { get; set; }
    public string? Autor { get; set; }
}

4-  Criar a pasta Services e nesta pasta criar a interface ILivroService

public interface ILivroService
{
    IEnumerable<Livro> GetAll();
    Livro Add(Livro livro);
    Livro GetById(Guid id);
    void Remove(Guid id);
}

5- Vamos implementar esta interface na classe LivroService

using ApiLivraria.Models;

namespace ApiLivraria.Services;

public class LivroService : ILivroService
{
      private readonly List<Livro> _livros;

        public LivroService()
        {
            _livros = new List<Livro>()
            {
                new Livro()
                {
                    Id = new Guid("ab2bd817-98cd-4cf3-a80a-53ea0cd9c200"),
                    Titulo="Gerenciando você mesmo",
                    Autor= "Peter Ducker",
                },
                new Livro()
                {
                    Id= new Guid("117366b8-3541-4ac5-8732-860d698e26a2"),
                    Titulo="Evolutionary Psychology",
                    Autor= "David Buss",
                },
                new Livro()
                {
                    Id= new Guid("66ff5116-bcaa-4061-85b2-6f58fbb6db25"),
                    Titulo="Clean Architecture",
                    Autor= "Uncle Bob"
                },
                new Livro()
                {
                    Id =  new Guid("cd5089dd-9754-4ed2-b44c-488f533243ef"),
                    Titulo = "Domain Driven Design",
                    Autor = "Vaugh Vernon"
                },
                new Livro()
                {
                    Id =  new Guid("d81e0829-55fa-4c37-b62f-f578c692af78"),
                    Titulo = "Unit Test - TDD",
                    Autor = "Will & Ariel Durant"
                }
            };
        }

        public IEnumerable<Livro> GetAll()
        {
            return _livros;
        }

        public Livro Add(Livro livro)
        {
            livro.Id = Guid.NewGuid();
            _livros.Add(livro);
            return livro;
        }

        public Livro GetById(Guid id) => _livros.Where(a => a.Id == id).FirstOrDefault();

        public void Remove(Guid id)
        {
            var existing = _livros.First(a => a.Id == id);
            _livros.Remove(existing);
        }
}

Criamos o serviço para fornecer alguns dados em memória e atuar como um repositório.

5- Criar o controlador LivrosController na pasta Controllers:

using Microsoft.EntityFrameworkCore;
using TodoApi.Models;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddDbContext<TodoContext>(opt =>
            opt.UseInMemoryDatabase("TodoList"));

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

6- Criar na pasta Controllers o controlador LivrosController onde vamos usar o serviço criado injetando no construtor e definindo os endpoints da API:

using ApiLivraria.Models;
using ApiLivraria.Services;
using Microsoft.AspNetCore.Mvc;

namespace ApiLivraria.Controllers;

[Route("[controller]")]
[ApiController]
public class LivrosController : ControllerBase
{
    private readonly ILivroService _service;

    public LivrosController(ILivroService service)
    {
        _service = service;
    }

    // GET /livros
    [HttpGet]
    public ActionResult<IEnumerable<Livro>> Get()
    {
        var items = _service.GetAll();
        return Ok(items);
    }

    // GET /livros/5
    [HttpGet("{id}")]
    public ActionResult<Livro> Get(Guid id)
    {
        var item = _service.GetById(id);

        if (item == null)
        {
            return NotFound();
        }

        return Ok(item);
    }

    // POST /livros
    [HttpPost]
    public ActionResult Post([FromBody] Livro value)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var item = _service.Add(value);
        return CreatedAtAction("Get", new { id = item.Id }, item);
    }

    // DELETE /livros/5
    [HttpDelete("{id}")]
    public ActionResult Remove(Guid id)
    {
        var existingItem = _service.GetById(id);

        if (existingItem == null)
        {
            return NotFound();
        }

        _service.Remove(id);
        return Ok();
    }
}

Executando o projeto usando o comando dotnet run teremos o resultado abaixo:

Esta será a o projeto que iremos testar.

Criando o projeto de Teste

Para facilitar o nosso trabalho vamos criar na pasta do projeto ApiLivraria um arquivo de solução - sln - e a seguir vamos incluir o projeto ApiLivraria.csproj neste arquivo para podemos trabalhar com o Visual Studio 2022.

1- Criando o arquivo de Solução

dotnet new sln

2- Incluindo o arquivo de projeto na solução

dotnet sln ApiLivraria.sln add ApiLivraria.csproj

Agora podemos abrir o projeto a ser testado no VS 2022 e criar o projeto de teste.

Com o projeto ApiLivraria aberto selecione o menu File e clique em Add->New Project e escolha o template : xUnit Test Project e a seguir informe o nome ApiLivraria.Tests e clique em Next;

Ao confirmar e criar o projeto teremos o resultado abaixo exibindo o projeto de testes :

A primeira coisa a fazer é incluir uma referência no projeto ApiLivraria.Tests ao projeto ApiLivraria usando a opção Add-> Project Reference.

Agora vamos ajustar o nome classe UnitTest1.cs para ApiLivrariaTest.cs

Com isso nosso projeto de testes esta pronto para ser usado e já esta referenciando o projeto a ser testado e podemos iniciar os testes de unidade no projeto ApiLivraria.

Vamos fazer isso na próxima parte do artigo.

"Louvai ao SENHOR todas as nações, louvai-o todos os povos.
Porque a sua benignidade é grande para conosco, e a verdade do Senhor dura para sempre. Louvai ao Senhor."
Salmos 117:1,2

Referências:


José Carlos Macoratti