0

我正在尝试编写一个辅助类,给定一个 type 的对象INotifyPropertyChanged,它可以帮助您验证给定的属性更改确实触发了PropertyChanged事件。这是我们经常遵循的模式,所以我制作了以下课程来帮助编写单元测试:

public class PropertyChangeHelper<TClass, TProperty> where TClass : class, INotifyPropertyChanged
{
    #region Fields
    private readonly TClass _model;
    private readonly string _propertyName;
    private readonly Action<TProperty> _setter;
    #endregion Fields
            
    #region Properties
    public bool ChangeEventFired { get; private set; }
    #endregion Properties
    
    #region Construction
    public PropertyChangeHelper(TClass model, Expression<Func<TClass, TProperty>> property)
    {
        _model = model ?? throw new ArgumentNullException(nameof(model));
        
        if (!(property.Body is PropertyExpression propertyExpression))
            throw new ArgumentException("The given expression must be for a property, i.e., with { get; set; }.", nameof(property));

        _propertyName = propertyExpression.PropertyInfo.Name;
        _setter = targetValue => propertyExpression.PropertyInfo.SetValue(_model, targetValue);
    }

    ~PropertyChangeHelper() => _model.PropertyChanged -= RecordPropertyChange;
    #endregion Construction
            
    #region Methods
    /// <summary>
    /// Updates the property's value to the given target value.
    /// </summary>
    public void UpdateProperty(TProperty targetValue) => _setter.Invoke(targetValue);

    private void RecordPropertyChange(object _, PropertyChangedEventArgs args)
    {
        if (args.PropertyName == _propertyName)
            ChangeEventFired = true;
    }
    #endregion Methods
}

这个想法是能够传入一个对象(通常是一个 VM)和一个 lambda 表达式来指定有问题的属性,然后告诉它更新值并检查事件是否被触发(或者没有,如果值是相同)。单元测试可能看起来像这样:

[Test]
public void Test()
{
    var vm = new VM();
    var helper = new PropertyChangeHelper<VM, int>(vm, x => x.SomeIntProperty);
    
    helper.UpdateProperty(5);
    
    Assert.IsTrue(helper.ChangeEventFired);
}

然而,我遇到的问题是我收到Expression参数错误,指出“Argument type 'lambda expression' is not assignable to parameter type FastExpressionCompiler.LightExpression.Expression<System.Func<VM, int>>

我在其他库(例如 Moq)中看到了完全相同的事情,所以我不知道为什么这不起作用。任何人都可以阐明编译器对此不喜欢什么吗?

4

0 回答 0