使用FluentValidation验证模拟的函数结果?

时间:2013-10-01 12:34:51

标签: c# moq fluentvalidation

我确定我会以错误的方式使用FluentValidation,我尝试搜索但可能没有使用正确的术语。任何帮助表示赞赏。

所以,我正在使用一个库,因为它处理文件系统,我正在嘲笑它(感谢它有接口,所以我可以很快这样做!)

我正在尝试模拟的对象(代表一个excel工作表)有一个本质上称为“IsEmpty(boolean aBooleanToSet)”的方法。

我可以用Moq写下这个:

mockWorkbook.Setup(m => m.IsEmpty(It.IsAny<bool>())).Returns(true);

我的验证器类非常简单,如下所示:

public class InvoiceDetailsWorksheetValidator : AbstractValidator<IXLWorksheet>
{
    public InvoiceDetailsWorksheetValidator()
    {
        RuleFor(x => x.IsEmpty())
            .NotEqual(true).WithMessage("Worksheet must not be empty.");
    }
}

我使用xUnit.net进行了以下测试:

[Fact]
public void Validate_WithFirstWorksheetEmpty_ReturnsInvalid()
{
       // Get the otherwise valid worksheet
       var mockWorkbook = TestHelper.GetMockValidInvoiceDetailsWorksheet();

       // Set the one specific value to a mocked failure
        mockWorkbook.Setup(m => m.IsEmpty(It.IsAny<bool>())).Returns(true);

       // Pass the mock object to the validator
       var validationResults = new InvoiceDetailsWorksheetValidator().Validate(mockWorkbook.Object);

       // Assert that the validator finds it invalid
       Assert.False(validationResults.IsValid);
}

当我运行测试时,而不是它通过,我看到来自FluentValidation的以下错误:

  

System.InvalidOperationException

     

无法自动确定表达式x =&gt;的属性名称x.IsEmpty()。
  请通过调用'WithName'指定自定义属性名称。

我做错了什么?

1 个答案:

答案 0 :(得分:1)

Jeremy Skinner,FluentValidation的作者,非常友好地为我提供了an explanation on its discussion forum

基本上,FluentValidation允许您测试方法,但您必须为它们指定属性名称,因为FluentValidation本身就是为测试属性而构建的。

所以解决方案是采用我原来的验证:

       RuleFor(x=>x.IsEmpty())
            .NotEqual(true).WithMessage("Worksheet must not be empty.");

...并在末尾添加OverridePropertyName()方法,如下所示:

       RuleFor(x=>x.IsEmpty())
            .NotEqual(true).WithMessage("Worksheet must not be empty.").OverridePropertyName("IsEmpty");

(作为旁注,如果你需要对业务对象进行验证,我非常推荐这个库。非常方便,很少让我失望,而Jeremy非常支持项目及其用户。)