Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何模拟使用规则集的抽象验证器?_C#_Moq_Fluentvalidation - Fatal编程技术网

C# 如何模拟使用规则集的抽象验证器?

C# 如何模拟使用规则集的抽象验证器?,c#,moq,fluentvalidation,C#,Moq,Fluentvalidation,我有一个抽象验证器,具有以下结构: public abstract class RiskAssessmentServiceCreateRequestValidator<T> : AbstractValidator<T> where T : IRiskAssessmentServiceCreateRequest { public RiskAssessmentServiceCreateRequestValidator(ApplicationCo

我有一个抽象验证器,具有以下结构:

public abstract class RiskAssessmentServiceCreateRequestValidator<T>
    : AbstractValidator<T> where T
        : IRiskAssessmentServiceCreateRequest
{
    public RiskAssessmentServiceCreateRequestValidator(ApplicationContext context)
    {
        RuleSet("modelBinding", () =>
        {
            RuleFor(x => x.ServiceProviderId).NotNull().GreaterThan(0);
        });

        RuleSet("handler", () =>
        {
            //....
        });

    }
}
如何在单元测试中模拟特定的调用以进行验证?如果我不使用规则集,我的设置将如下所示:

_validator.Setup(x => x.Validate(It.IsAny<CreateRequest>()))
          .Returns(validationResult);
_validator.Setup(x => x.Validate(
                It.IsAny<CreateRequest>(), 
                (IValidatorSelector)null,
                It.IsAny<string>()))
           .Returns(validationResult);
_validator
    .Setup(x => x.Validate(It.IsAny<ValidationContext<CreateRequest>>())
    .Returns(validationResult);
\u validator.Setup(x=>x.Validate(It.IsAny()))
.返回(验证结果);
不允许进行以下调用,因为表达式树中不允许使用可选参数:

_validator.Setup(x => x.Validate(
                It.IsAny<CreateRequest>(), 
                ruleSet: It.IsAny<string>()))
          .Returns(validationResult);
\u validator.Setup(x=>x.Validate(
It.IsAny(),
规则集:It.IsAny())
.返回(验证结果);
理论上我可以这样设置:

_validator.Setup(x => x.Validate(It.IsAny<CreateRequest>()))
          .Returns(validationResult);
_validator.Setup(x => x.Validate(
                It.IsAny<CreateRequest>(), 
                (IValidatorSelector)null,
                It.IsAny<string>()))
           .Returns(validationResult);
_validator
    .Setup(x => x.Validate(It.IsAny<ValidationContext<CreateRequest>>())
    .Returns(validationResult);
\u validator.Setup(x=>x.Validate(
It.IsAny(),
(IValidatorSelector)null,
It.IsAny())
.返回(验证结果);
但这会导致:

System.NotSupportedException : Unsupported expression: x => x.Validate<CreateRequest>(It.IsAny<CreateRequest>(), null, It.IsAny<string>())
    Extension methods (here: DefaultValidatorExtensions.Validate) may not be used in setup / verification expressions.
System.NotSupportedException:不支持的表达式:x=>x.Validate(It.IsAny(),null,It.IsAny())
在安装/验证表达式中不能使用扩展方法(此处:DefaultValidatorExtensions.Validate)。
除了使用我想要避免的真实验证器之外,我如何解决这个问题并以合适的方式设置Moq?

试试看

var mock = new Mock<AbstractValidator<object>>();
mock.Setup(x => x.Validate(It.Is<ValidationContext<object>>(ctx => IsExpectedRuleSet(ctx, new[] { "Rule1", "Rule2" }))))
    .Return(...);

mock.Object.Validate(new object(), ruleSet: "Rule1,Rule2");

bool IsExpectedRuleSet(ValidationContext context, string[] expectedRuleSet)
{
    return (context.Selector as FluentValidation.Internal.RulesetValidatorSelector)?.RuleSets.SequenceEqual(expectedRuleSet) == true;
}
var mock=new mock();
mock.Setup(x=>x.Validate(It.Is(ctx=>IsExpectedRuleSet(ctx,new[]{“Rule1”,“Rule2”})))
.返回(…);
验证(新对象(),规则集:“规则1,规则2”);
bool IsExpectedRuleSet(ValidationContext上下文,字符串[]expectedRuleSet)
{
返回(context.Selector作为FluentValidation.Internal.RulesetValidatorSelector)?.RuleSets.SequenceEqual(expectedRuleSet)==true;
}

这里有两个问题

  • 第一个是如何使用可选参数进行模拟-简单地处理可选参数是非可选的

  • 但是,您试图模拟一个扩展方法,这是不可能的。相反,您需要模拟扩展尝试调用的方法。粗略地看一下源代码,我认为它正在调用,所以您的Moq代码可能是这样的:

    _validator.Setup(x => x.Validate(It.IsAny<CreateRequest>()))
              .Returns(validationResult);
    
    _validator.Setup(x => x.Validate(
                    It.IsAny<CreateRequest>(), 
                    (IValidatorSelector)null,
                    It.IsAny<string>()))
               .Returns(validationResult);
    
    _validator
        .Setup(x => x.Validate(It.IsAny<ValidationContext<CreateRequest>>())
        .Returns(validationResult);
    
    \u验证程序
    .Setup(x=>x.Validate(It.IsAny())
    .返回(验证结果);
    

  • 在模拟时,将可选参数视为非可选参数。但是,该方法看起来是一个扩展方法,因此您无法模拟它。相反,您仍然模拟扩展调用的实际底层方法。例如,它看起来像是在引擎盖下调用的,但这是一个猜测。@DavidG猜对了