Uma aplicação em C# (web) com Minimal APIs, EFCore 6, MySQL e Pomelo
Pacote:
dotnet add package Swashbuckle.AspNetCore
Código:
builder.Services.AddSwaggerGen();
builder.Services.AddEndpointsApiExplorer();
...
app.UseSwagger();
app.UseSwaggerUI();
Código:
app.UseDefaultFiles();
app.UseStaticFiles();
Banco: https://github.com/ermogenes/minhas-tarefas-mysql
Para subir o MySQL com Docker:
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=1234 mysql:8.0.28
Foi utilizada a lib Pomelo (Pomelo.EntityFrameworkCore.MySql
) em vez do Connector/NET oficial da Oracle, devido ao suporte simplificado a diferentes versões do MySQL.
Comandos utilizados para fazer o scaffolding:
dotnet tool install --global dotnet-ef
dotnet tool update --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Pomelo.EntityFrameworkCore.MySql
dotnet ef dbcontext scaffold "server=localhost;port=3306;uid=root;pwd=1234;database=tarefas" Pomelo.EntityFrameworkCore.MySql -o db -f --no-pluralize
String de conexão transferida de tarefasContext.OnConfiguring
para appsettings.json
:
"ConnectionStrings": {
"tarefasConnection": "server=localhost;port=3306;uid=root;pwd=1234;database=tarefas"
}
Exemplo:
...
builder.Services.AddDbContext<tarefasContext>(opt =>
{
string connectionString = builder.Configuration.GetConnectionString("tarefasConnection");
var serverVersion = ServerVersion.AutoDetect(connectionString);
opt.UseMySql(connectionString, serverVersion);
});
...
app.MapGet("/api/tarefas", ([FromServices] tarefasContext _db) =>
{
return Results.Ok(_db.Tarefa.ToList<Tarefa>());
});
...
Hashing de senha:
dotnet add package CryptoHelper
Autenticação e autorização com JWT:
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
builder.Services.Configure<Microsoft.AspNetCore.Http.Json.JsonOptions>(opt =>
{
opt.SerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
});
dotnet new sln
Criar a solução:
dotnet new xunit -o Tarefas.Tests
Adicionar a referência do projeto nos testes:
dotnet add reference ../Tarefas/Tarefas.csproj
Adicionar os pacotes:
dotnet add package Microsoft.AspNetCore.Mvc.Testing
Tornar o Program
do projeto acessível aos testes:
<ItemGroup>
<InternalsVisibleTo Include="Tarefas.Tests" />
</ItemGroup>
Criar uma instância de WebApplicationFactory<Program>
. Executando CreateClient()
você tem acesso a uma instância de Program
.
É possível sobrescrever IHost CreateHost(IHostBuilder builder)
e alterar como desejar os objetos injetados.
O exemplo remove o repositório injetado e injeta um novo que usa outro contexto (no app é MySQL, nos testes é Sqlite em memória). Também faz uma carga inicial (que funciona como Arrange dos testes).
Outra estratégia possível é não usar repositório, e reinjetar diretamente um contexto. Não é recomendado utilizar In Memory Databases para testes de integração.