使用 BindingExpression 中的数据进行 WPF 测试验证规则

问题描述 投票:0回答:1

我有以下问题,我想测试 WPF 中的 ValidationRule 是否按预期工作。 我的 ValidationRule 使用 BindingExpression 中定义的 DataItem 中的一些数据。

调用 Validate 函数不是问题,但我没有计划如何为 BindingExpression 参数设置模拟。 我尝试使用 Moq 创建一个模拟,但它是一个密封类,因此这是不可能的。 我尝试使用构造函数创建一个实例,但构造函数是内部的,因此这也是不可能的。

有什么解决方案可以设置 BindingExpression,也可以在内部提供一些数据进行测试吗?

c# wpf testing validationrule
1个回答
0
投票

如果您无法模拟参数,您始终可以引入一个接受未包装数据的中间方法。继承的 API 必须委托给这个新的中间 API。您还可以将数据转换为新类型,而不是解包它。

以下示例展示了如何将数据转换为可模拟对象,以便您可以正确测试行为:

示例ValidationRule.cs

class ExampleValidationRule : ValidationRule
{
  public override ValidationResult Validate(object value, CultureInfo cultureInfo, BindingExpressionBase owner)
  {
    // Store the required information in the BindingInfo.
    // Consider using a constructor over the initializer for more convenience.
    var bindingInfo = new BindingInfo()
    {
      Source = ((BindingExpression)owner).ResolvedSource
    };

    // And delegate to a custom API
    return Validate(value, cultureInfo, bindingInfo);
  }

  // Use this method to test the Validate override. Here you can mock the BindingInfo if required.
  // From an internal point of view or design perspective, 
  // this method is the true entry point of the validation logic. 
  // The inherited base methods are only!!! used to delegate the parameters to this method.
  // This allows to ignore the inherited Validate methods in your unit test
  // as they contain no functionality.
  public ValidationResult Validate(object value, CultureInfo cultureInfo, BindingInfo owner)
  {
    // TODO::Implemet the validation here
  }
}

BindingInfo.cs
包含

BindingExpression
相关信息的可模拟类。

考虑在应用程序代码中使用构造函数以更加方便,但使用重载以避免测试代码中的

BindingExpressionBase
或对象初始值设定项。

class BindingInfo
{
  public object Source { get; init set; }

  public BindingInfo(BindingExpressionBase bindingExpressionBase)
  {
    // For the sake of an example
    this.Source = bindingExpressionBase is BindingExpression bindingExpression
      ? bindingExpression.ResolvedSource
      : null;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.