Problem Details
ASP.NET Core writes error responses in the RFC 9457 problem details format from Results.Problem(), Results.ValidationProblem(), [ApiController] model validation and the exception handler, and frameworks such as Wolverine do the same. Your application might too. Alba has assertions for these responses:
cs
[Fact]
public async Task problem_details_members()
{
await _host.Scenario(x =>
{
x.Post.Url("/withdrawals");
x.ShouldReturnProblemDetails(409)
.WithTitle("Insufficient funds")
.WithDetail("The balance is 10.00")
.WithType("https://example.com/problems/insufficient-funds")
.WithExtension("balance", 10m)
.WithExtension("limits", new[] { 5, 50 });
});
}
[Fact]
public async Task validation_errors_by_field()
{
await _host.Scenario(x =>
{
x.Post.Url("/deposits");
x.ShouldReturnValidationProblem()
.WithValidationError("Amount", "must be positive")
.WithValidationError("amount", "two decimal places")
.WithValidationError("Currency");
});
}ShouldReturnProblemDetails(statusCode)asserts the status code and theapplication/problem+jsoncontent type.ShouldReturnValidationProblem()also requires anerrorsmember. The status code defaults to 400; pass another one, such as 422, if the application uses it.WithTitle(...),WithDetail(...)andWithType(...)compare those members exactly.WithExtension(name, value)compares an extension member structurally, serializing the expected value with the application's JSON settings in the same way asJsonPath(...).WithValidationError(field)asserts that a field has a validation error. Field names are matched without regard to case, because applications differ in how they case the keys. Pass a second argument to require that one of the field's messages contains that text.
All failures are reported together with the response body.
