验证我的方法是否使用 Moq 调用
本文关键字:Moq 调用 是否 我的 方法 验证 | 更新日期: 2023-09-27 18:31:15
我有以下类:
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));
}
}
我基本上想测试在为我的 SearchTerm 属性设置值时是否使用正确的参数("搜索术语")调用了"RaisePropertyChanged"方法。
我想我必须嘲笑我的班级。如何使用最小起订量执行此操作?
这不是 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));
也许最小起订量不是在那里使用的最佳工具。
如果您将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));
为了使箭头x => x.RaisePropertyChanged("SearchTerm", true)
编译,方法RaisePropertyChanged
必须可从测试代码所在的位置访问。由于它是一种protected
方法,因此您必须在某个类中制作测试代码,该类(是)或派生自RaisePropertyChanged
。如果不方便,您可以接受放宽RaisePropertyChanged
的访问级别,例如:
protected internal virtual void RaisePropertyChanged( ... )
...
然后,测试只需位于同一程序集(项目)中即可。
否则,您可以使用Moq对protected
成员的支持,但它有点丑陋:
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.