How would you test a minimal api that uses a dictionary for saving entities?

aspnetcorelearner 0 Reputation points
2023-08-14T23:00:51.0533333+00:00

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!

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,551 questions
Visual Studio Testing
Visual Studio Testing
Visual Studio: A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.Testing: The act or process of applying tests as a means of analysis or diagnosis.
349 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.