CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl-labs/aspnet-testing

Integration tests for ASP.NET Core APIs — WebApplicationFactory, xUnit, ConfigureTestServices, FluentAssertions, database isolation

97

1.45x
Quality

96%

Does it follow best practices?

Impact

99%

1.45x

Average score across 5 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

task.mdevals/scenario-2/

Add Comprehensive Tests to an Inventory Management API

Problem/Feature Description

A small logistics company uses an internal ASP.NET Core API to track warehouse inventory. The API has been running for six months with no tests. A recent incident where a deployment broke the /api/items endpoint went undetected for two hours caused a significant disruption. The engineering manager has mandated that a minimum set of integration tests be added immediately to catch regressions before deployment.

The test infrastructure has already been scaffolded for you — a CustomWebApplicationFactory exists and is connected to the API project. Your task is to populate the test class with tests that cover the realistic failure modes the team has identified: missing data, bad inputs, resources that don't exist, and ensuring that after a write operation the data is actually retrievable. The error handling team has also requested verification that all error responses from the API share the same JSON envelope structure so clients can handle errors generically.

Produce the test class file(s) with the full set of meaningful integration tests for the API endpoints below.

Output Specification

Produce the following files:

  • tests/InventoryApi.Tests/InventoryTests.cs — the test class with all integration tests
  • tests/InventoryApi.Tests/CustomWebApplicationFactory.cs — the factory (may reuse or extend the stub below)

The tests do not need to actually compile and run — the grader will inspect the source code of the test files.

Input Files

The following files are provided as inputs. Extract them before beginning.

=============== FILE: inputs/src/InventoryApi/Program.cs =============== using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args); builder.Services.AddDbContext<InventoryDb>(opt => opt.UseInMemoryDatabase("Inventory"));

var app = builder.Build();

app.MapGet("/api/items", async (InventoryDb db) => Results.Ok(new { data = await db.Items.ToListAsync() }));

app.MapGet("/api/items/{id:int}", async (int id, InventoryDb db) => { var item = await db.Items.FindAsync(id); return item is null ? Results.NotFound(new { error = new { message = "Item not found" } }) : Results.Ok(new { data = item }); });

app.MapPost("/api/items", async (ItemRequest req, InventoryDb db) => { if (string.IsNullOrWhiteSpace(req.Sku)) return Results.BadRequest(new { error = new { message = "SKU is required" } });

var item = new InventoryItem { Sku = req.Sku, Quantity = req.Quantity };
db.Items.Add(item);
await db.SaveChangesAsync();
return Results.Created($"/api/items/{item.Id}", new { data = item });

});

app.Run();

=============== FILE: inputs/src/InventoryApi/Models.cs =============== public class InventoryItem { public int Id { get; set; } public string Sku { get; set; } = ""; public int Quantity { get; set; } }

public record ItemRequest(string Sku, int Quantity);

=============== FILE: inputs/src/InventoryApi/InventoryDb.cs =============== using Microsoft.EntityFrameworkCore;

public class InventoryDb : DbContext { public InventoryDb(DbContextOptions<InventoryDb> options) : base(options) { } public DbSet<InventoryItem> Items => Set<InventoryItem>(); }

=============== FILE: inputs/tests/InventoryApi.Tests/CustomWebApplicationFactory.cs =============== using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection;

public class CustomWebApplicationFactory : WebApplicationFactory<Program> { protected override void ConfigureWebHost(Microsoft.AspNetCore.Hosting.IWebHostBuilder builder) { // TODO: configure test services here builder.UseEnvironment("Testing"); } }

evals

tile.json