How would you test a minimal api that uses a dictionary for saving entities?
Here's my Program.cs file (I've actually simplified it to some extent).
using StudentsMinimalApi;
using StudentsMinimalApi.Validation;
using System.Collections.Concurrent;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddProblemDetails();
WebApplication app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler();
}
app.UseStatusCodePages();
ConcurrentDictionary<string, Student> _students = new();
RouteGroupBuilder studentsApi = app.MapGroup("/student");
studentsApi.MapGet("/", () => _students);
RouteGroupBuilder studentsApiWithValidation = studentsApi
.MapGroup("/"); //I use a filter factory on this builder, but it does not matter for my question.
studentsApiWithValidation.MapGet("/{id}", (string id) =>
_students.TryGetValue(id, out var student)
? TypedResults.Ok(student)
: Results.Problem(statusCode: 404));
studentsApiWithValidation.MapPost("/{id}", (Student student, string id) =>
_students.TryAdd(id, student)
? TypedResults.Created($"/student/{id}", student)
: Results.ValidationProblem(new Dictionary<string, string[]>
{
{ "id", new[] { "A student with the given id already exists." } }
}));
app.Run();
public partial class Program { }
As you can see, I created an example minimal API that exposes endpoints that you can use to access or change data related to an example Student class using the HTTP protocol.
So now I'd like to test my minimal API using xUnit. That's how I decided to test if the post method successfully creates a new student.
[Fact]
public async Task MapPost_Should_Successfully_Create_A_New_Student()
{
await using var application = new WebApplicationFactory<Program>();
using HttpClient? client = application.CreateClient();
HttpResponseMessage? resultFromPost = await client.PostAsJsonAsync("/student/s1", new Student("X", "Y", "Z"));
HttpResponseMessage? resultFromGet = await client.GetAsync("/student/s1");
Assert.Equal(HttpStatusCode.Created, resultFromPost.StatusCode);
Assert.Equal(HttpStatusCode.OK, resultFromGet.StatusCode);
string? contentAsString = await resultFromGet.Content.ReadAsStringAsync();
var contentAsStudentObject =
JsonConvert.DeserializeObject<Student>(contentAsString);
Assert.Equal(HttpStatusCode.Created, resultFromPost.StatusCode);
Assert.Equal(HttpStatusCode.OK, resultFromGet.StatusCode);
Assert.NotNull(contentAsStudentObject);
Assert.Equal("X", contentAsStudentObject.FirstName);
Assert.Equal("Y", contentAsStudentObject.LastName);
Assert.Equal("Z", contentAsStudentObject.FavouriteSubject);
}
May I ask you if this way of testing is adequate? For the testing of the post method I've actually used the get method. This does not seem like a good approach, but I don't see how else I can handle the situation. So I can't compe up with another alternative that's maybe better than this. Is there a way for me to access the _students dictionary from the Program.cs file? How would you write your tests in this situation? Thank you in advance!