Gerenciamento de CORS e Testes - Curso de Criação de uma API de Exemplo em C#
Ao trabalhar com APIs web em C#, o CORS (Cross-Origin Resource Sharing) frequentemente se torna um obstáculo, especialmente quando o frontend e o backend estão em domínios ou portas diferentes. É um cenário comum no desenvolvimento de software moderno, onde APIs servem clientes de front-end como Blazor WebAssembly, Angular ou React.
Em seu tutorial em vídeo sobre " Gerenciando CORS e Testando - Criando uma API de Exemplo em C# ", Tim Corey demonstra como gerenciar CORS de forma eficaz ao criar e testar uma API de exemplo. Essa abordagem ajuda os desenvolvedores não apenas a corrigir problemas de origem cruzada, mas também a se prepararem para técnicas de teste mais avançadas, como testes unitários, testes de integração e fluxos de trabalho automatizados.
Vamos analisar o vídeo e seguir as instruções do Tim passo a passo.
Configurando o frontend Blazor
Tim inicia a aula criando um projeto simples de front-end em Blazor WebAssembly chamado SampleTestUI. Este frontend não está pronto para produção; trata-se de um projeto de teste para verificar a conectividade com a API e provocar intencionalmente um problema de CORS.
-
Tim usa o modelo .NET 9 e opta por não usar os recursos de autenticação ou PWA.
- O objetivo do frontend é simular chamadas de API do mundo real e expor falhas de teste relacionadas a solicitações de origem cruzada.
Ele modifica a página inicial para chamar o endpoint da API /courses e exibir uma lista de cursos com as respectivas imagens.
O frontend utiliza uma classe de modelo simples (CourseModel) criada separadamente, em vez de compartilhar o modelo com a API. Tim enfatiza que os modelos de front-end devem ser separados dos modelos de acesso a dados para reduzir o acoplamento e aumentar a capacidade de manutenção (2:28). Este é um princípio importante ao escrever testes de fácil manutenção e código testável.
Escrevendo a chamada da API
Para obter dados da API:
- Tim injeta um HttpClient.
Ele escreve um método assíncrono usando Http.GetFromJsonAsync <List
- O método está codificado com a URL da API local (4:00), servindo como um teste simples para validar a comunicação entre o frontend e o backend.
Aqui não há método de teste nem tratamento de erros, apenas uma chamada direta. Essa configuração espelha os primeiros passos na escrita de testes unitários, onde você começa validando a interação básica entre os componentes.
Criando a lógica de busca de dados e a interface do usuário.
Após definir o URL da API às 4:00, Tim se concentra em construir a lógica principal para buscar os dados do curso na API e exibi-los no frontend Blazor . Este é um passo crucial para validar se o frontend consegue interagir com o backend, mesmo antes de escrever testes automatizados ou usar uma estrutura de testes.
Primeiro, ele garante que a URL correta seja usada a partir do arquivo launchSettings.json da API — obtendo o endereço HTTPS e adicionando /courses para formar o endpoint completo. Isso é importante porque os navegadores geralmente rejeitam chamadas de API não HTTPS provenientes de páginas seguras.
courses = await Http.GetFromJsonAsync<List<CourseModel>>("https://localhost:port/courses");
courses = await Http.GetFromJsonAsync<List<CourseModel>>("https://localhost:port/courses");
Exibindo os dados
Após a obtenção dos dados, Tim escreve um loop de interface do usuário simples usando a sintaxe Razor para iterar pela lista de cursos:
@foreach (var c in courses) { <a href="@c.CourseUrl"> <img width="300" src="@c.CourseImage" /> </a> }
@foreach (var c in courses) { <a href="@c.CourseUrl"> <img width="300" src="@c.CourseImage" /> </a> }
Cada curso é apresentado como uma imagem envolta em um hiperlink. Tim observa que as imagens são grandes (1920x1080), então ele limita a largura a 300px para evitar sobrecarregar a página.
Essa saída serve como uma confirmação visual de que os dados da API estão fluindo corretamente para o frontend. Isso simula o tipo de feedback que você esperaria de um método de teste aprovado — se as imagens aparecerem, a solicitação foi bem-sucedida.
Preparando-se para o lançamento
Antes de executar o aplicativo, Tim configura vários projetos de inicialização no Visual Studio. Ele configura o projeto da API para iniciar primeiro, seguido pelo frontend Blazor . Essa ordem é essencial para garantir que a API esteja pronta quando o frontend tentar buscar dados.
Esta etapa final, às 6h30, prepara o terreno para a execução do teste — e para o encontro com o erro CORS —, que é onde começa a próxima parte do tutorial.
Enfrentando o obstáculo do CORS
Ao executar ambos os projetos simultaneamente usando o explorador de soluções do Visual Studio, Tim faz com que a interface tente chamar a API, mas falhe. O console do navegador exibe uma mensagem familiar:
"O acesso para buscar em '[URL da API]' a partir da origem '[URL do Frontend]' foi bloqueado pela política CORS..."(7:02)
É aqui que a compreensão e a gestão do CORS se tornam essenciais. Sem os cabeçalhos adequados, o navegador bloqueia as solicitações de uma origem para outra.
Criando uma classe de configuração CORS
Em vez de sobrecarregar o arquivo Program.cs, Tim cria uma classe dedicada chamada CorsConfig em uma pasta Startup. Ele utiliza uma estrutura de classe estática para aplicar o mesmo padrão de configuração usado para o Swagger e a configuração do OpenAPI.
Isso está em consonância com as práticas de código limpo e torna o aplicativo mais testável. Configurações modulares como essa também facilitam a escrita de métodos de teste unitário posteriormente, porque a lógica fica isolada e mais fácil de simular ou sobrescrever.
Aplicando uma política CORS permissiva
Tim define uma política CORS muito aberta para permitir acesso total entre origens diferentes:
policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
Essa configuração é útil no desenvolvimento orientado a testes e em testes de integração, onde serviços externos ou aplicativos de front-end precisam de acesso total à API. Tim chama essa política de "AllowAll" e armazena o nome em uma constante para evitar erros de digitação e inconsistências (11:00):
private const string AllowAllPolicy = "AllowAll";
private const string AllowAllPolicy = "AllowAll";
Ele destaca que isso não deve ser usado em produção, mas é ideal para testar APIs localmente ou dentro de contêineres Docker, onde os desenvolvedores estão experimentando ou escrevendo testes unitários em endpoints reais.
Integrando a configuração em Program.cs
Tim registra os serviços CORS e aplica a configuração em Program.cs:
builder.Services.AddCorsServices(); app.ApplyCorsConfig();
builder.Services.AddCorsServices(); app.ApplyCorsConfig();
Essa modularidade melhora a qualidade do código e facilita a adição de frameworks de mocking ou a injeção de comportamentos de teste no futuro. Isso reflete a forma como você estruturaria as coisas para testes unitários em C#, onde ter configurações centralizadas pode simplificar a configuração dos testes.
Testando novamente o frontend
Após aplicar a correção de CORS, Tim executa novamente ambos os aplicativos. Desta vez, o frontend Blazor funciona como esperado: os dados do curso são carregados com sucesso e cada imagem do curso possui um link para o URL correspondente.
É importante ressaltar que nenhuma alteração foi feita na interface. A correção completa ocorreu no nível da API, por meio da configuração adequada do CORS.
Lições sobre estratégia de teste e configuração
Embora Tim não aborde diretamente as estruturas de teste de unidade neste vídeo, sua abordagem estabelece as bases para isso. Eis como:
Ele separa as responsabilidades de forma clara, possibilitando o uso de classes de teste e objetos simulados no futuro.
-
O arquivo de configuração CORS dedicado pode ser reutilizado ou substituído por uma configuração simulada durante os testes.
- Seu projeto rápido de front-end funciona como um teste de integração manual — uma validação inicial antes de escrever projetos completos de teste unitário.
Isso reflete a forma como você abordaria os testes no Visual Studio:
-
Crie um projeto de teste unitário em paralelo com sua aplicação principal.
-
Utilize o Test Explorer para executar todos os métodos de teste e acompanhar os resultados.
-
Simule dependências externas, como requisições HTTP, chamadas a bancos de dados ou arquivos de configuração.
- Escreva testes unitários simples para validar o comportamento esperado e, em seguida, expanda-os para abranger casos de teste com condições extremas.
Considerações sobre testes unitários para cenários CORS
Embora o vídeo de Tim trate principalmente da configuração do CORS, as implicações para os testes de software são claras:
Você pode criar métodos de teste unitário que validem seus serviços de configuração.
-
Utilizando frameworks de mocking, simule fatores externos como diferentes origens ou métodos HTTP.
-
Execute testes como parte do seu processo de CI/CD para confirmar se seus métodos de teste são aprovados de forma consistente.
- Incorpore testes no Explorador de Testes do Visual Studio para acompanhar as falhas e garantir a estabilidade.
Conclusão
Neste tutorial em vídeo , Tim Corey oferece um exemplo prático de gerenciamento de CORS em uma API Web C# enquanto cria um frontend Blazor simples para testar a conectividade. Sua abordagem não se limita a corrigir um erro do navegador; ela estabelece uma estrutura que incentiva a manutenção de código, uma arquitetura limpa e a fácil extensão para testes automatizados.
A partir daqui, os desenvolvedores podem avançar com confiança para a escrita de testes unitários, configuração de testes de integração e uso de ferramentas como Visual Studio, Test Explorer e frameworks de mocking para melhorar a qualidade e a confiabilidade do código.
Quer você esteja aprendendo como iniciar os testes, escrever seu primeiro teste unitário ou garantir que os métodos de teste falhem quando esperado, esta lição fornece a base para um processo de desenvolvimento sólido. E o mais importante: tudo começa com a arquitetura e a configuração corretas.

