gpt4 book ai didi

c# - Moq:使用 FluentValidation 运行流程

转载 作者:行者123 更新时间:2023-11-28 20:26:38 24 4
gpt4 key购买 nike

我正在使用 FluentValidation 来验证请求。如果验证失败,则不应调用 UseCaseHandler。在 UseCaseHandler 中,我使用了 IRepository,检查是否调用了 UseCaseHandler

请求验证器

 public class MyValidator: AbstractValidator<Request>
{
public MyValidator()
{
RuleFor(rq=> rq)
.Cascade(CascadeMode.Continue);
RuleFor(rq=> rq)
.Must(property => property.id != default(Guid))
.WithMessage(message => $"invalid id.")
.WithName(member => nameof(member.Id));

}
}

这是测试

[Fact]
public async Task Test()
{
Mock<IUnitOfWork> uowMock = new Mock<IUnitOfWork>();
Mock<IRepository> repositoryMock = new Mock<IRepository>(MockBehavior.Strict);
Mock<IValidator<Request>> validatorMock = new Mock<IValidator<Request>>(MockBehavior.Strict);

var request = new Request
{
Id = Guid.NewGuid()
};

validatorMock
.Setup(validator => validator.Validate(request))
.Returns(new ValidationResult());

repositoryMock
.Setup(repo => repo.SaveAsync(It.IsAny<object>()))
.Returns(Task.CompletedTask);

var sut = new UseCase(uowMock.Object, repositoryMock.Object, validatorMock.Object);


Func<Task> act = () => sut.UseCaseHandler(request);


await act.Should().NotThrowAsync();
repositoryMock.Verify(repo => repo.SaveAsync(It.IsAny<object>()), Times.Once);
}

我希望编写一个测试来检查流程。

如果验证失败,则测试应该失败并且不应调用 SaveAsync。

如果验证成功,则测试也应该成功,并且应该调用一次 SaveAsync。

写测试的方法是什么?

更新

这是用例类定义。

UseCaseHandlerProxy 是一个充当代理的抽象基类

public class UseCase : UseCaseHandlerProxy<Request, Response>
{
private readonly IRepository _repository;


public UseCase(IUnitOfWork unitOfWork, IRepository repository, IValidator<Request> validator)
: base(unitOfWork, validator)
{
_repository = repository
}

public override async Task<Response> UseCaseHandler(Request request)
{
Order order = new Order();

order.Create();

await _repository.SaveAsync(order);

return new Response(order.Id);
}
}

这是请求类定义

class Request
{
public Guid Id { get; set; }
}

Te 响应只返回相同的 Id

代理类

public abstract class UseCaseHandlerProxy<TRequest, TResponse> : IUseCaseHandler<TRequest, TResponse>
where TRequest : IRequest
where TResponse : Response
{
private IValidator<TRequest> Validator { get; }
protected internal IUnitOfWork UnitOfWork { get; }


public UseCaseHandlerProxy(IUnitOfWork unitOfWork, IValidator<TRequest> validator)
{
Validator = validator;
UnitOfWork = unitOfWork;
}

async Task<TResponse> IUseCaseHandler<TRequest, TResponse>.HandleAsync(TRequest request)
{
ValidationResult validationResult = await Validator.ValidateAsync(request);

TResponse response;

if (!validationResult.IsValid)
{
response = (TResponse)System.Activator.CreateInstance(typeof(TResponse));

validationResult.Errors.ToList().ForEach(error => response.AddError(error.PropertyName, error.ErrorMessage));

return response;
}

response = await UseCaseHandler(request);

return response;
}

public abstract Task<TResponse> UseCaseHandler(TRequest request);
}

最佳答案

鉴于您要测试的流程,我会说您调用了错误的成员。

sutIUseCaseHandler<TRequest, TResponse>访问 HandleAsync这就是所需的流程。

例如,以下验证如果没有验证错误,则存储库调用保存。

[Fact]
public async Task UseCase_Should_Save() {
//Arrange
Mock<IUnitOfWork> uowMock = new Mock<IUnitOfWork>();
Mock<IRepository> repositoryMock = new Mock<IRepository>(MockBehavior.Strict);
Mock<IValidator<Request>> validatorMock = new Mock<IValidator<Request>>(MockBehavior.Strict);

var request = new Request {
Id = Guid.NewGuid()
};

validatorMock
.Setup(validator => validator.ValidateAsync(request, It.IsAny<CancellationToken>()))
.ReturnsAsync(new ValidationResult());

repositoryMock
.Setup(repo => repo.SaveAsync(It.IsAny<object>()))
.Returns(Task.FromResult((object)null));

var sut = new UseCase(uowMock.Object, repositoryMock.Object, validatorMock.Object) as IUseCaseHandler<Request, Response>;

//Act
Func<Task> act = () => sut.HandleAsync(request);

//Assert
await act.Should().NotThrowAsync();
repositoryMock.Verify(repo => repo.SaveAsync(It.IsAny<object>()), Times.Once);
}

下面验证如果有错误,则版本库不保存

[Fact]
public async Task UseCase_Should_Not_Save() {
//Arrange
var uowMock = new Mock<IUnitOfWork>();
var repositoryMock = Mock.Of<IRepository>();
var validatorMock = new Mock<IValidator<Request>>(MockBehavior.Strict);

var request = new Request {
Id = Guid.NewGuid()
};

var result = new ValidationResult();
result.Errors.Add(new ValidationFailure("SomeProperty", "SomeError"));

validatorMock
.Setup(validator => validator.ValidateAsync(request, It.IsAny<CancellationToken>()))
.ReturnsAsync(result);

var sut = new UseCase(uowMock.Object, repositoryMock, validatorMock.Object) as IUseCaseHandler<Request, Response>;

//Act
Func<Task> act = () => sut.HandleAsync(request);

//Assert
await act.Should().NotThrowAsync();
Mock.Get(repositoryMock).Verify(repo => repo.SaveAsync(It.IsAny<object>()), Times.Never);
}

关于c# - Moq:使用 FluentValidation 运行流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53710685/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com