I'm writing a test that verifies if my controller calls my query with expected query arguments. This is my query class:
public class GetProducts : IRequest<IEnumerable<Product>>
{
public int CategoryId { get; set; }
}
This implements IRequest<T>
MediatR interface.
This is the test case that does not work:
[Theory]
[InlineData(1)]
public async Task GetProductsAsync_GivenValidRequestParameters_ReturnsListGetProductsResponseAsync(int categoryId)
{
var expectedQuery = new GetProducts
{
CategoryId = categoryId
};
_mediatorMock
.Setup(s => s.Send(It.IsAny<GetProducts>(), It.IsAny<CancellationToken>()))
.Callback<GetProducts, CancellationToken>((query, ct) => query.Should().BeEquivalentTo(expectedQuery))
.ReturnsAsync(Enumerable.Empty<Product>());
var response = await _productsController.GetProductsAsync(categoryId);
response.Result.Should().BeOfType<OkObjectResult>();
_mediatorMock.Verify(s => s.Send(It.IsAny<GetProducts>(), It.IsAny<CancellationToken>()), Times.Once);
}
This is the controller I'm testing:
[ApiController]
[Route("categories/{categoryId:int}/products")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
[TrackUsage]
public class ProductsController : ControllerBase
{
private readonly IMediator _mediator;
public ProductsController(IMediator mediator)
{
_mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
}
[HttpGet]
public async Task<ActionResult<IEnumerable<GetProductsResponse>>> GetProductsAsync([FromRoute]int categoryId)
{
var query = new GetProducts
{
CategoryId = categoryId
};
var products = await _mediator.Send(query);
return Ok(products.ToResponse());
}
}
It complains because it cannot find an callback with <GetProducts, CancellationToken>
as parameters even though it seems right.
I know I could use It.Is<...>(callback => true)
to check each and every property, but there could be queries with multiple properties and I'd prefer to test that using FluentAssertion.