[英]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.