[英]How to unit test Command Handler in CQRS pattern in C#
我正在 C# 中学习和练习 CQRS 和单元测试。 我需要知道如何在 CQRS 中对命令处理程序进行单元测试。
这是我的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);
}
}
}
这是我的单元测试:
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);
}
}
当我调试上述测试时,
mockUnitOfWork
作为构造函数参数传递给AddCommandHandler
? 如果我可以通过mockUnitOfWork
,我可以在我的AuthorRepository
中验证AddAsync
调用。 请协助我做错了什么。
您正在测试处理程序,所以不是这个
var result = mockHandler.Object.Handle(command);
...创建一个实际的 AddCommandHandler 实例并注入它所需的依赖项,即
var mockUnitOfWork = new Mock<IUnitOfWork>();
var handler = new AddCommandHandler(mockUnitOfWork.Object);
当您调用Handle时,您现在将进入您的实现。
如果您想保留 Internal 访问修饰符,您可以使用 InternalsVisibleTo 属性来授予对您的测试项目的访问权限,例如在定义处理程序的项目中执行此操作,
[assembly: InternalsVisibleTo(“UnitTests”)]
https://anthonygiretti.com/2018/06/27/how-to-unit-test-internal-classes-in-net-core-applications/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.