C# 验证是否使用Moq调用了我的方法

C# 验证是否使用Moq调用了我的方法,c#,unit-testing,moq,C#,Unit Testing,Moq,我有以下课程: public class ConsignorViewModel : ViewModel { #region Members private Consignor _model; #endregion #region Properties public string SearchTerm { get { return _model.SearchTerm; } set {

我有以下课程:

public class ConsignorViewModel : ViewModel
{
    #region Members
    private Consignor _model;
    #endregion

    #region Properties

    public string SearchTerm
    {
        get { return _model.SearchTerm; }
        set
        {
            if (_model.SearchTerm != value)
            {
                _model.SearchTerm = value;
                RaisePropertyChanged("SearchTerm");
            }
        }
    }

    ...
    #endregion Properties

    protected void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpresssion)
    {
        var propertyName = PropertySupport.ExtractPropertyName(propertyExpresssion);
        this.RaisePropertyChanged(propertyName);
    }

    protected void RaisePropertyChanged(String propertyName, bool validatePropertyName = true)
    {
        if(validatePropertyName) VerifyPropertyName(propertyName);
        OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }
}
公共类委托人ViewModel:ViewModel
{
#区域成员
私人委托人模型;
#端区
#区域属性
公共字符串搜索项
{
获取{return}model.SearchTerm;}
设置
{
if(_model.SearchTerm!=值)
{
_model.SearchTerm=值;
RaisePropertyChanged(“搜索术语”);
}
}
}
...
#端域属性
受保护的void RaisePropertyChanged(表达式属性Expression)
{
var propertyName=PropertySupport.ExtractPropertyName(PropertyExpression);
this.RaisePropertyChanged(propertyName);
}
受保护的void RaisePropertyChanged(字符串propertyName,bool validatePropertyName=true)
{
if(validatePropertyName)VerifyPropertyName(propertyName);
OnPropertyChanged(新PropertyChangedEventArgs(propertyName));
}
}
我主要想测试在设置SearchTerm属性的值时,是否使用正确的参数(“SearchTerm”)调用了“RaisePropertyChanged”方法


因此,我想我不得不嘲笑我的班级。我如何使用Moq实现这一点?

这不是Moq的用例-您不能模拟测试中的类

但是您可以像下面这样测试
INotifyPropertyChanged
模式:

var vm = new ConsignorViewModel();
var raised = 0;

vm.PropertyChanged += (sender, e) => {
  if (e.PropertyName == "SearchTerm")
    ++raised;
  else
    Assert.Fail("Unexpected property name");
}

vm.SearchTerm = "42";
Assert.That(raised, Is.EqualTo(1));

也许Moq不是最好的工具

如果您将
RaisePropertyChanged
方法
virtual
,则可以使用Moq执行此操作:

protected virtual void RaisePropertyChanged(String propertyName, bool validatePropertyName = true)
    ...
那么这就行了:

var mock = new Mock<ConsignorViewModel>(MockBehavior.Loose /* , constructorArguments */);

// use mock
mock.Object.SearchTerm = "42";

// verify the call
mock.Verify(x => x.RaisePropertyChanged("SearchTerm", true));
然后测试必须在同一个程序集(项目)中

否则,您可以使用Moq对受保护的成员的支持,但这有点难看:

using Moq.Protected;

...

// verify the call
mock.Protected().Verify("RaisePropertyChanged", Times.Once(), "SearchTerm", true);
// Note that "RaisePropertyChanged" is a string,
// since the name RaisePropertyChanged is not in scope.

这是虚拟的吗?如果您想使用Moq(我不知道这是否是一种糟糕的方法),它需要是
虚拟的
(或非
密封的
覆盖)。它是
受保护的内部
还是
公共
?我添加了RaisePropertyChanged方法的代码。效果很好,但没有更简单的方法吗?对我来说,似乎有很多代码,因为我有很多属性。您可以执行一次测试,但不使用计数器,而是使用
列表
存储更改属性的名称。更改一组属性,然后检查列表是否与您期望的相同。
using Moq.Protected;

...

// verify the call
mock.Protected().Verify("RaisePropertyChanged", Times.Once(), "SearchTerm", true);
// Note that "RaisePropertyChanged" is a string,
// since the name RaisePropertyChanged is not in scope.