I’m working on an ASP.NET Core 8 Web API with CQRS mediator pattern and I’m currently creating tests for all the controllers. Everything’s working fine, expect I cannot create tests for BadRequest
responses, as the client which calls the controller throws a “Bad Request” exception without allowing me to control it.
My test (which is supposed to test a create where I’m trying to insert a duplicated license):
public async Task Create400()
{
using var scope = _lab.AppFactory.Services.CreateScope();
var provider = scope.ServiceProvider;
// Arrange
var events = await _lab.InitAsync(provider, true);
var licensesRepository = provider.GetRequiredService<IVdcQueryRepository<Licenses>>();
var request = new CreateUpdateRequest
{
Name = $"New license",
MaxCpu = 8,
ParentId = null
};
// Act
var responseAlreadyExists = await _client.CreateBadRequest(_lab.Identity, request);
// Assert
// whatever
}
The client to call controller:
public async Task<LicenseResponse> CreateBadRequest(IdentityInfo identity, CreateUpdateRequest request, string? correlationId = null, CancellationToken ct = default)
{
var (response, statudCode) = await ApiClient.SendAsync<LicenseResponse>(
HttpMethod.Post,
$"/api/license",
message => message.AddAuthorization(identity, _options.ApiKey, correlationId),
model: request,
ct: ct
);
return response!;
}
In this client:
response => My entity.
statusCode => System.Net.HttpStatusCode
The controller:
[HttpPost]
public async Task<ActionResult<LicenseResponse>> Create(
[FromServices][IsSensitive] ICommandDispatcher dispatcher,
[FromBody] CreateUpdateRequest request, CancellationToken ct = default)
{
var ipAddress = HttpContext.GetIPAddress();
var identity = HttpContext.GetIdentity();
var httpRequest = HttpContext.Request;
var command = new CreateCommand(identity, HttpContext.TraceIdentifier)
{
CreateLicense = request,
IpAddress = ipAddress
};
var result = await dispatcher.DispatchAsync(_provider, command, ct);
return result.ToActionResult(this);
}
The validator in the Mediator CreateCommand
handler:
public async ValueTask<IResponse> ValidatorAsync(CreateCommand request, RequestValidator<CreateCommand> validator, CancellationToken ct = default)
{
var licenses = await _repository.FindAll().ToListAsync();
var errorMsg = "There is another license with the same name. Please, choose a different one.";
validator.RuleFor(r => r.CreateLicense.Name)
.Must(_ =>
{
return licenses.Where(x => x.Name.ToLower() == request.CreateLicense.Name.ToLower()).ToArray().Length == 0;
}).WithMessage(errorMsg);
return request.OkResponse();
}
The client is working fine for a Create
test, but when I try to create a test for a duplicated name (for example), the validator will throw a 400, and so the controller, and my client (which is calling the controller) instead of allowing me to control that 400 is throwing an exception and exiting the test.
How do I create a test case for a 400 Bad Request given my scenario / structure?