Alura > Cursos de Programação > Cursos de .NET > Conteúdos de .NET > Primeiras aulas do curso Testes em .NET: aplicando testes de integração em APIs

Testes em .NET: aplicando testes de integração em APIs

Preparando o ambiente para os testes - Apresentação

Olá, boas-vindas para mais um curso da formação de teste em .NET aqui na Alura!

Meu nome é André Bessa e serei seu instrutor. Por questões de acessibilidade, vou me autodescrever.

Audiodescrição: André é um homem negro, com barba e cabelo raspado. Está no ambiente dos estúdios da Alura, com iluminação ao fundo verde e azul e com uma estante com algumas decorações do lado direito.

Pré-requisitos

  1. Cursos dessa formação;
  2. conhecimento em C#;
  3. orientação a Objetos (OO);
  4. teste de unidade.

Para que você tenha maior aproveitamento neste curso, é altamente recomendável que você tenha feito os primeiros cursos desta formação. Tenha também conhecimentos na linguagem C#, em orientação a objetos e em testes de unidade.

O que vamos aprender?

Vamos explorar a criação de testes de integração para uma API do .NET com o auxílio do XUnit. Neste processo, faremos uso da biblioteca MVC Testing da Microsoft, a qual possibilita a criação desses testes.

Com essa mesma biblioteca, teremos a capacidade de configurar e reconfigurar uma instância da nossa API para execução em memória. Além disso, continuaremos a empregar a biblioteca Bogos para gerar conjuntos de dados para os nossos testes.

Vamos testar o status code das operações, além de validar o resultado, o retorno da execução das APIs, como por exemplo, a execução de uma consulta paginada. Também vamos utilizar algumas estratégias para permitir a criação de testes mais independentes.

Continuaremos trabalhando com o projeto de Jornada Milhas, que vem nos acompanhando desde o primeiro curso desta formação.

Gráfico esquemático de um Ambiente Docker com fundo escuro gradiente. No topo, em letras grandes, lê-se "Ambiente Docker". Abaixo, dois retângulos arredondados com fundo azul-turquesa, representando containers Docker. O retângulo da esquerda contém o texto "API [Container Docker]" e o da direita, "SQL Server [Container Docker]". Setas de dupla direção conectam os dois retângulos, indicando comunicação entre a API e o SQL Server dentro do ambiente Docker.

O diferencial deste curso é que vamos executar a API, e o banco SQL Server no ambiente Docker. O que vai nos trazer mais agilidade e praticidade no momento de executar a nossa aplicação.

Então, além dos vídeos, nós também temos uma série de atividades, como atividade de texto, desafios, mão na massa. Além de ter o apoio do fórum e uma comunidade bem ativa no Discord.

Vamos estudar?

Preparando o ambiente para os testes - Configurando o projeto de testes

Olá, pessoal! A Jornada Milhas evoluiu para uma solução de uma Web API, que já conta com alguns endpoints para rotas e ofertas de viagem. Nós, incluindo você e os demais colegas, ficamos responsáveis por implementar os testes de integração da nossa solução.

Entendendo as ferramentas e estrutura do projeto

Um detalhe importante para acompanhar o desenvolvimento do curso é ter instalado na sua máquina o Docker Desktop com o WSL2. Inclusive, vamos deixar uma atividade de preparação do ambiente para ser executada.

Agora, vamos executar a aplicação clicando em "Docker Compose" na parte superior. Perfeito! Ele vai iniciar o projeto e abrir o Swagger da solução no endereço localhost:50665/swagger/index.html. Temos a "Autenticação", "Oferta Viagem", "Rota Viagem" e alguns endpoints.

Vamos mostrar também o Docker Desktop rodando. Temos o Docker Compose com o JornadaMilhas.API, o projeto API, e o projeto Banco de Dados em execução (sqlserver-1). Portanto, temos dois containers: um da API e outro do Banco de Dados SQL Server.

Vamos minimizar o Docker Desktop e voltar para o projeto.

Temos a pasta src (source) do lado direito, onde temos o projeto API, dividimos também o projeto de dados e domínio.

Também temos uma pasta test onde vamos colocar o nosso projeto de teste de integração.

Essa é a arquitetura do projeto, e agora vamos começar a praticar.

Adicionando o projeto de teste

Adicionaremos o nosso projeto de teste. Na pasta test do lado direito, ao clicar com o botão direito, iremos incluir um novo projeto (Adicionar > Novo Projeto).

Na tela aberta, faremos uma pesquisa por "XuNIT" no campo de pesquisa. Selecionaremos o "Projeto de Teste do XUnit" na lista de resultados e clicamos no botão "Próximo" no canto inferior direito.

O nome do projeto, digitamos "JornadaMilhas.Integration.Test.API". O local, vamos salvá-lo dentro da pasta test, dentro do nosso projeto, nossa pasta de solução. Clicamos em "Próximo", vamos utilizar a estrutura do .NET 8.0(Suporte de Longo Prazo), que é a versão mais recente até a gravação. Clicamos no botão "Criar" na parte inferior direita.

JornadaMilhas.Integration.Test.API

namespace JornadaMilhas.Integration.Test.API
{
    public class UnitTest1
    {
        [Fact]
        public void Test1()
        {

        }
    }
}

Projeto criado, para trabalharmos com os projetos de integração, com o teste de integração, na nossa solução, vamos utilizar uma biblioteca da Microsoft chamada mvc.testing.

Adicionando a biblioteca

Vamos adicionar agora o nosso projeto. Do lado direito, clicamos em "Dependências" com o botão direito e depois optamos por "Gerenciar Pacotes do NuGet".

Do lado superior esquerdo, clicamos em "Procurar" e buscamos por: "Microsoft.AspNetCore.Mvc.Testing". Clicamos na opção exibida, aceitamos, e depois clicamos em "aplicar".

A biblioteca está instalada no nosso projeto, e a partir de agora, vamos começar a configurar a nossa solução, para podermos escrever nossos primeiros testes de integração, utilizando essa biblioteca.

O projeto já está configurado com a biblioteca que vamos trabalhar. Vamos fazer uma série de configurações, mas onde vamos buscar esse passo a passo? Na documentação oficial.

Testes de integração no ASP.NET Core

A documentação oficial dessa biblioteca vai permitir fazer o teste de integração. Nela, temos uma série de configurações que vamos executar, para podermos escrever nossos primeiros testes de integração, utilizando essa biblioteca mvc.testing.

Próximos Passos

Vamos começar a escrever o nosso primeiro teste de integração, mas antes disso, precisamos fazer uma série de configurações de acordo com a documentação, e vamos fazer isso na sequência.

Preparando o ambiente para os testes - Configurando o serviço

Acabamos de instalar em nosso projeto de teste a biblioteca Microsoft.AspNetCore.Mvc.Testing. É um nome bem extenso, então, a partir de agora, vamos nos referir a ela apenas como Testing.

Criando a classe JornadaMilhasWebApplicationFactory

Para utilizar a biblioteca, é necessário criar uma nova classe. Para isso, clicamos com o botão direito no projeto de test chamado de "JornadaMilhas.Integration.Test.API".

No menu exibido, selecionamos "Adicionar > classe". No campo "Nome" na parte inferior, digitamos "JornadaMilhasWebApplicationFactory". Logo após, clicamos no botão "Adicionar" no canto inferior direito.

JornadaMilhasWebApplicationFactory

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JornadaMilhas.Integration.Test.API
{
    internal class JornadaMilhasWebApplicationFactory
    {

    }
}

Essa classe utilizará a biblioteca Testing, possibilitando a criação de uma instância da nossa API em memória. Além disso, oferecerá um maior controle sobre essa instância em execução, permitindo a realização de diversas configurações, as quais vamos iniciar agora.

Com a classe criada, precisamos começar a escrevê-la para utilizá-la em nossa biblioteca. Inserimos dois pontos após o JornadaMilhasWebApplicationFactory e digitamos WebApplicationFactory, para indicar que estamos herdando desta biblioteca.

using Microsoft.AspNetCore.Mvc.Testing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JornadaMilhas.Integration.Test.API
{
    internal class JornadaMilhasWebApplicationFactory:WebApplicationFactory
    {

    }
}

Configurações da classe Program.cs

No entanto, para utilizar a WebApplicationFactory, precisaremos alterar algumas configurações do nosso servidor, da nossa API. Na sequência, precisamos fazer uma referência ao Program.

using Microsoft.AspNetCore.Mvc.Testing;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JornadaMilhas.Integration.Test.API
{
    internal class JornadaMilhasWebApplicationFactory:WebApplicationFactory<Program>
    {

    }
}

Mas para que essa configuração seja efetiva, também precisamos fazer uma configuração na nossa classe Program.cs, que precisa ser visível agora no nosso projeto de teste para essa classe WebApplicationFactory.

Vamos à classe Program.cs da API do lado direito e adicionamos ao final da nossa classe a seguinte configuração: public partial class Program { }.

Program.cs

// código omitido

public partial class Program { }

Agora conseguimos ver as configurações da nossa API na nossa classe WebApplicationFactory.

Feita a configuração, voltamos à nossa classe JornadaMilhasWebApplicationFactory. Observe que "Program" está com um sublinhado na cor vermelha.

Com essa configuração feita na classe Program.cs, precisamos colocar referência no nosso projeto de API. Para isso, em "Dependências" do lado direito, clicamos com o botão direito e selecionamos "Adicionar referência de projeto". Selecionamos JornadaMilhas.API e clicamos em "OK".

Agora, observe que o Program na linha 10 está na cor verde e sem o sublinhado.

Vamos também excluir os using não utilizados. Para isso, teclamos "Ctrl + ponto" e escolhemos "Remover Usos Desnecessários". Além disso, mudamos a visibilidade da nossa classe para public.

JornadaMilhasWebApplicationFactory

using Microsoft.AspNetCore.Mvc.Testing;

namespace JornadaMilhas.Integration.Test.API
{
    public class JornadaMilhasWebApplicationFactory:WebApplicationFactory<Program>
    {

    }
}

Essa classe nos possibilita criar uma instância da nossa API em execução na memória, que podemos reconfigurar e usar para testes. Vamos ajustar algumas opções disponíveis na classe. Atualmente, nossa API está apontando para o Container Docker que hospeda nosso banco de dados SQL Server.

Modificaremos essa configuração.

Vamos reconfigurar o seguinte: faremos Override no ConfigureWebHost(builder), recebendo o WebHostBuilder.

JornadaMilhasWebApplicationFactory

using Microsoft.AspNetCore.Mvc.Testing;

namespace JornadaMilhas.Integration.Test.API
{
    public class JornadaMilhasWebApplicationFactory:WebApplicationFactory<Program>
    {
            protected override void ConfigureWebHost(IWebHostBuilder builder)
            {
                base.ConfigureWebHost(builder);
            }
    }
}

Faremos a configuração da nossa string de conexão, agora apontando para esse Container rodando em memória. Configuraremos utilizando o objeto builder.ConfigureService()s. Dentro disso, faremos a configuração.

using Microsoft.AspNetCore.Mvc.Testing;

namespace JornadaMilhas.Integration.Test.API
{
    public class JornadaMilhasWebApplicationFactory:WebApplicationFactory<Program>
    {
            protected override void ConfigureWebHost(IWebHostBuilder builder)
            {
                builder.ConfigureServices(services =>
                {
                
                });
                base.ConfigureWebHost(builder);
            }
    }
}

A modificação inicial que desejamos fazer diz respeito à string de conexão. A string atualmente configurada está direcionada ao servidor SQL Server, mas está referenciando um Container que observa outro Container. Agora, precisamos acessar este Container a partir de uma instância em execução na memória.

Então, o primeiro passo é o seguinte: services.RemoveAll(). Vamos eliminar a configuração que adiciona nosso DbContext.

using Microsoft.AspNetCore.Mvc.Testing;

namespace JornadaMilhas.Integration.Test.API
{
    public class JornadaMilhasWebApplicationFactory:WebApplicationFactory<Program>
    {
            protected override void ConfigureWebHost(IWebHostBuilder builder)
            {
                builder.ConfigureServices(services =>
                {
                    services.RemoveAll(typeof(DbContextOptions<JornadaMilhasContext>));
                    
                });
                base.ConfigureWebHost(builder);
            }
    }
}

Em seguida, vamos reconfigurar isso. Vamos inserir a nova string de conexão com o Container.

Para isso, temos um trecho de código pronto aqui para agilizar o processo. Assim, utilizamos services.AddDbContext, passando a referência do JornadaMilhas. No entanto, a string de conexão que utilizaremos, Localhost.11433, estará apontada para o Container.

using Microsoft.AspNetCore.Mvc.Testing;

namespace JornadaMilhas.Integration.Test.API
{
    public class JornadaMilhasWebApplicationFactory:WebApplicationFactory<Program>
    {
            protected override void ConfigureWebHost(IWebHostBuilder builder)
            {
                builder.ConfigureServices(services =>
                {
                      services.RemoveAll(typeof(DbContextOptions<JornadaMilhasContext>));
                      services.AddDbContext<JornadaMilhasContext>(options =>
           options
           .UseLazyLoadingProxies()
           .UseSqlServer
                 ("Server=localhost,11433;Database=JornadaMilhasV3;User Id=sa;Password=Alura#2024;Encrypt=false;TrustServerCertificate=true;MultipleActiveResultSets=true;"));
            });

                base.ConfigureWebHost(builder);
            }
    }
}

Estamos utilizando a nossa classe WebApplicationFactory, que nos permite reconfigurar essa instância da nossa API em memória. E qual a configuração que fizemos? Estamos agora apontando, utilizando uma string de conexão, que aponta para esse Container Docker em execução, o nosso SQL Server.

A string muda um pouco porque precisamos fazer essa instância em memória, coletando um Docker. Anteriormente, tínhamos um Container Docker acessando esse outro Container Docker.

Próximos Passos

Com essa primeira configuração, já conseguimos escrever o nosso primeiro método de teste, e vamos fazer isso na sequência.

Sobre o curso Testes em .NET: aplicando testes de integração em APIs

O curso Testes em .NET: aplicando testes de integração em APIs possui 89 minutos de vídeos, em um total de 48 atividades. Gostou? Conheça nossos outros cursos de .NET em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda .NET acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas