我正在使用FluentValidation验证请求。如果验证失败,则# Generator
def gen():
for val in range(10):
while True:
val = yield val
if val is None: break
# Generator Wrapper
class Pushable:
def __init__(self, g):
self.g = g
self._next = None
def send(self, x):
if self._next is not None:
raise RuntimeError("Can't pushback twice without pulling")
self._next = self.g.send(x)
def __iter__(self):
try:
while True:
# Have to clear self._next before yielding
if self._next is not None:
(tmp, self._next) = (self._next, None)
yield tmp
else:
yield next(self.g)
except StopIteration: return
# Calling code
num_pushed = 0
f = Pushable(gen())
for x in f:
print(x)
if (x == 5) and (num_pushed in [0,1,2]):
f.send(x)
num_pushed += 1
不应该被调用。在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));
}
}
我正在寻找写一个可以检查流程的测试。
如果验证失败,则测试将失败,并且不应调用SaveAsync。
如果验证成功,则测试也应该成功,并且SaveAsync应该被调用一次。
编写测试的方式是什么?
更新
这是用例类定义。
[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);
}
是充当代理的基本抽象类
UseCaseHandlerProxy
这是Request类的定义
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);
}
}
Te响应仅返回相同的ID
代理类
class Request
{
public Guid Id { get; set; }
}
答案 0 :(得分:2)
鉴于您要测试的流程,我会说您正在调用错误的成员。
将sut
投射到IUseCaseHandler<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);
}