I'm learning and practicing CQRS and Unit Test in C#. I need to know how to unit test Command Handlers in CQRS.
Here is my CreateAuthorCommand
:
public sealed class CreateAuthorCommand : ICommand<Author>
{
public CreateAuthorCommand(string firstName, string lastName, DateTimeOffset dateOfBirth, string mainCategory, IEnumerable<CreateBookDto> books)
{
FirstName = firstName;
LastName = lastName;
DateOfBirth = dateOfBirth;
MainCategory = mainCategory;
Books = books;
}
public string FirstName { get; }
public string LastName { get; }
public DateTimeOffset DateOfBirth { get; private set; }
public string MainCategory { get; }
public IEnumerable<CreateBookDto> Books { get; }
[AuditLog]
[DatabaseRetry]
internal sealed class AddCommandHandler : ICommandHandler<CreateAuthorCommand, Author>
{
private readonly IUnitOfWork _unitOfWork;
public AddCommandHandler(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork));
}
public async Task<Result<Author>> Handle(CreateAuthorCommand command)
{
var nameResult = Name.Create(command.FirstName, command.LastName);
var birthDateResult = BirthDate.Create(command.DateOfBirth);
var mainCategoryResult = Entities.Authors.MainCategory.Create(command.MainCategory);
var authorResult = Result.Combine(nameResult, birthDateResult, mainCategoryResult)
.Map(() => new Author(nameResult.Value, birthDateResult.Value, null, mainCategoryResult.Value));
if (authorResult.IsFailure)
return Result.Failure<Author>(authorResult.Error);
await _unitOfWork.AuthorRepository.AddAsync(authorResult.Value);
await _unitOfWork.SaveChangesAsync();
return Result.Success(authorResult.Value);
}
}
}
Here is my Unit Test:
public class CreateAuthorCommandTests
{
[Fact]
public void Create_Author_Should_Call_Add_Method_Once()
{
var fixture = new Fixture();
var command = fixture.Create<CreateAuthorCommand>();
var mockUnitOfWork = new Mock<IUnitOfWork>();
var mockHandler = new Mock<ICommandHandler<CreateAuthorCommand, Author>>();
var result = mockHandler.Object.Handle(command);
mockUnitOfWork.Verify(x => x.AuthorRepository.AddAsync(It.IsAny<Author>()), Times.Once);
}
}
When I debug the above test,
- I'm not able to step into Handler Method!!
- How to pass
mockUnitOfWork
as constructor parameter toAddCommandHandler
?
If I can pass mockUnitOfWork
, the I can verify the AddAsync
call inside my AuthorRepository
. Please assist on what I'm doing wrong.
AddCommandHandler
using reflection – Grogram