I am trying to build an xUnit Test project for an MVC Core 2.2 Application that is based on the CQRS/ES pattern. I utilize MediatR as part of my CQRS/ES pattern in the MVC application.
In one of my commands which I would like to test, I inject MediatR to publish an event once a customer record has been updated. Kind of like this:
public class UpdateCustomerCommandHandler : IRequestHandler<UpdateCustomerCommand>
{
public IMediator Mediator { get; set; }
public UpdateCustomerCommandHandler(IMediator mediator)
{
Mediator = mediator;
}
public Task<Unit> Handle(UpdateCustomerCommand request, CancellationToken cancellationToken)
{
//do some stuff
Mediator.Publish(new CustomersChanged());
return Task.FromResult(new Unit());
}
}
When writing a unit test for this command, I obviously also must create an instance of MediatR (or a mockup) which I then pass to to the command during test execution.
[Fact]
public async void UpdateCustomerCommand_CustomerDataUpdatedOnDatabase()
{
//Arange
var mediator = new Mediator(); // doesn't work that way..
UpdateCustomerCommand command = new UpdateCustomerCommand();
UpdateCustomerCommandHandler handler = new UpdateCustomerCommandHandler(mediator);
//Act
Unit x = await handler.Handle(command, new System.Threading.CancellationToken());
//Asert
//Do the assertion
}
However, instanciating MediatR (outside of the MVC application, where I can utilize the existing dependency injection implementation) seems to be not that simple and frankly speaking I actually do not understand how I can do in my test method.
I understand that I potentially could use a dependency injection framework for which MediatR already provides an implementation (Ninject, etc.), but I actually do not want to use any other third party libraries in my unit tests apart from MediatR, just for the sake of creating an instance.
Is there a simpler way to instantiate MediatR which I might have overseen?
You're on the right lines with or a mockup
- you need to mock the IMediator
There's a few mocking libraries out there:
Moq is one of the most popular, so, using your test as an example:
[Fact]
public async void UpdateCustomerCommand_CustomerDataUpdatedOnDatabase()
{
//Arange
var mediator = new Mock<IMediator>();
UpdateCustomerCommand command = new UpdateCustomerCommand();
UpdateCustomerCommandHandler handler = new UpdateCustomerCommandHandler(mediator.Object);
//Act
Unit x = await handler.Handle(command, new System.Threading.CancellationToken());
//Asert
//Do the assertion
//something like:
mediator.Verify(x=>x.Publish(It.IsAny<CustomersChanged>()));
}