Search code examples
c#.netunit-testingasp.net-coreminimal-apis

Asserting IResult when retuning an Anonymous Type


I am learning Minimal APIs (and also still learning C#), but just got stuck when creating Unit Tests. Given this function:

public IResult GetGenderById(Guid id)
    {
        var gender = this.repository.Get(id);
        if (gender != null)
        {
            return Results.Ok(gender);
        }
        return Results.NotFound();
    }

I can easily assert the IResult, for example: Assert.That(result, Is.InstanceOf<Ok<GenderData>>()); or Assert.That(result, Is.InstanceOf<NotFound>());.

However, if I was to return a message with the NotFound, I suddenly cannot assert for this IResult, thanks to the Anonymous Type:

public IResult GetGenderById(Guid id)
    {
        var gender = this.repository.Get(id);
        if (gender != null)
        {
            return Results.Ok(gender);
        }
        return Results.NotFound(new { Message = "No 'Gender' found with the given ID." });
    }

One of the solutions I have found is to run Integrations Tests instead, where I can directly check the returned JSON, but I am hoping to Unit Test this method, and later on to run Integration Tests. I cannot find many resources online regarding Minimal APIs (compared to MVC and Controllers).

Thank you!


Solution

  • If you don't want to introduce a type for the result (though with record's it is very easy and I would go this way) you have several workarounds.

    You can check for the status code:

    var sutResult = Results.NotFound(new { Message = "No 'Gender' found with the given ID." });
    
    Assert.That(sutResult, Is.AssignableTo<IStatusCodeHttpResult>());
    Assert.That((sutResult as IStatusCodeHttpResult).StatusCode,Is.EqualTo((int)HttpStatusCode.NotFound));
    

    Or use some reflection:

    Assert.That(sutResult.GetType().GetGenericTypeDefinition(), Is.EqualTo(typeof(NotFound<>)));
    

    Probably combined with reflection based asserts (might require to remove warnings):

    Assert.That(sutResult, Has.Property("Value").Property("Message").Contains("Gender"));