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
The team at BrightCart has built a small ASP.NET Core Web API for managing a product catalog. The API has been running in production for a month but has zero automated tests. Every deployment is a manual risk. The tech lead has asked you to get integration tests in place before the next release.
You have been given the source code of the API below. Your job is to set up a complete integration test project wired to this API — including the project scaffolding, required dependencies, and a custom test host configuration that replaces the real database with an in-memory one for isolation. Include at least one smoke-test to confirm the setup is working.
Produce a working .NET solution with:
setup.sh script that, when run in a fresh environment with the .NET SDK installed, creates the solution, adds the test project, installs packages, and runs dotnet test successfullyThe setup.sh script is the primary grading artifact. It must be self-contained and produce output that shows at least one test passing.
The following files are provided as inputs. Extract them before beginning.
=============== FILE: inputs/src/ProductCatalog/ProductCatalog.csproj =============== <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.0" /> </ItemGroup> </Project>
=============== FILE: inputs/src/ProductCatalog/Program.cs =============== using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext<AppDbContext>(opt => opt.UseInMemoryDatabase("ProductDb"));
var app = builder.Build();
app.MapGet("/api/products", async (AppDbContext db) => Results.Ok(new { data = await db.Products.ToListAsync() }));
app.MapGet("/api/products/{id}", async (int id, AppDbContext db) => { var product = await db.Products.FindAsync(id); return product is null ? Results.NotFound(new { error = new { message = "Product not found" } }) : Results.Ok(new { data = product }); });
app.MapPost("/api/products", async (ProductInput input, AppDbContext db) => { if (string.IsNullOrWhiteSpace(input.Name)) return Results.BadRequest(new { error = new { message = "Name is required" } });
var product = new Product { Name = input.Name, Price = input.Price };
db.Products.Add(product);
await db.SaveChangesAsync();
return Results.Created($"/api/products/{product.Id}", new { data = product });});
app.Run();
=============== FILE: inputs/src/ProductCatalog/AppDbContext.cs =============== using Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Product> Products => Set<Product>(); }
=============== FILE: inputs/src/ProductCatalog/Models.cs =============== public class Product { public int Id { get; set; } public string Name { get; set; } = ""; public decimal Price { get; set; } }
public record ProductInput(string Name, decimal Price);