如何在测试中模拟 FluentValidation ValidationResults

这是我要测试的方法:

public async Task<object> CreateExpense(CreateExpenseCommand command)
{
    var validationResults = await _validator.ValidateAsync(command);
    if (!validationResults.IsValid)
    {
        return validationResults.Errors.First().ToString();
    }
    //more code that is irrelevant for this post
}

为了测试这一点,我需要模拟 _validatior,它被定义为 private readonly IValidator<CreateExpenseCommand> _validator; 并通过构造函数注入使用。

我将 AutoFixture 与 AutoMoqCustomizations 和 Moq 结合使用进行模拟。也许我应该只使用 Moq?

这是我在测试中尝试做的:

[Fact]
public async Task CreateExpense_Success()
{
    //Arrange
    var service = _fixture.Fixture.Freeze<Mock<IValidator<CreateExpenseCommand>>>();
    service.Setup(x => x.Validate((CreateExpenseCommand)It.IsAny<IValidator<CreateExpenseCommand>>())).Returns(It.IsAny<ValidationResult>);
    
    //more code that is irrelevant for this post
}

然而,这会导致错误:

System.NullReferenceException: '对象引用未设置为对象的实例'。

错误不言自明,但我不知道如何正确模拟。

错误图片:

如何在测试中模拟 FluentValidation ValidationResults

tuxiangzhen 回答:如何在测试中模拟 FluentValidation ValidationResults

设置时需要返回一个对象:

service.Setup(x => x.Validate(It.IsAny<IValidator<CreateExpenseCommand>>()))
    .Returns(<*1>);

*1 - 这里返回调用 ValidateAsync 函数时希望返回的对象。不要执行 It.IsAny,因为它返回 null 导致 NullReferenceException

此外,您需要在 virtual 方法中添加 ValidateAsync 以使其可被覆盖。

本文链接:https://www.f2er.com/2299.html

大家都在问