Integration tests for ASP.NET Core APIs — WebApplicationFactory, xUnit, ConfigureTestServices, FluentAssertions, database isolation
97
96%
Does it follow best practices?
Impact
99%
1.45xAverage score across 5 eval scenarios
Passed
No known issues
TechCorp's internal HR portal exposes an ASP.NET Core API with several endpoints that are protected by JWT bearer authentication. The QA team needs to add integration tests for these protected routes but cannot use real JWT tokens in the CI/CD pipeline — token generation requires a live identity provider that isn't available in the test environment.
The team needs a way to test the protected endpoints without modifying the production code. A previous developer started a test project but did not implement the authentication bypass — the protected endpoints currently return 401 in tests, making them untestable. Your task is to implement the authentication infrastructure needed to test these secured routes and add tests that verify the protected endpoints behave correctly for an authenticated user.
Produce the following files:
tests/HrPortal.Tests/TestAuthHandler.cs — the test authentication handlertests/HrPortal.Tests/SecuredApiFactory.cs — a WebApplicationFactory that wires up the test auth handlertests/HrPortal.Tests/EmployeeEndpointTests.cs — tests for the protected endpointsThe grader will inspect the source code of these files directly.
The following files are provided as inputs. Extract them before beginning.
=============== FILE: inputs/src/HrPortal/Program.cs =============== using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer();
builder.Services.AddAuthorization(); builder.Services.AddDbContext<HrDb>(opt => opt.UseInMemoryDatabase("HrDb"));
var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization();
// Public endpoint app.MapGet("/health", () => Results.Ok(new { status = "healthy" }));
// Protected endpoints app.MapGet("/api/employees", async (HrDb db) => Results.Ok(new { data = await db.Employees.ToListAsync() })) .RequireAuthorization();
app.MapPost("/api/employees", async (EmployeeInput input, HrDb db) => { if (string.IsNullOrWhiteSpace(input.Name)) return Results.BadRequest(new { error = new { message = "Name is required" } });
var emp = new Employee { Name = input.Name, Department = input.Department };
db.Employees.Add(emp);
await db.SaveChangesAsync();
return Results.Created($"/api/employees/{emp.Id}", new { data = emp });}) .RequireAuthorization();
app.Run();
=============== FILE: inputs/src/HrPortal/Models.cs =============== public class Employee { public int Id { get; set; } public string Name { get; set; } = ""; public string Department { get; set; } = ""; }
public record EmployeeInput(string Name, string Department);
=============== FILE: inputs/src/HrPortal/HrDb.cs =============== using Microsoft.EntityFrameworkCore;
public class HrDb : DbContext { public HrDb(DbContextOptions<HrDb> options) : base(options) { } public DbSet<Employee> Employees => Set<Employee>(); }