我正在编写单元测试并在尝试从抽象类mock中引发事件时收到异常。以下是示例代码:
public abstract class AbstractBase : EntityObject
{}
[TestMethod]
public void MyTest()
{
var mock = new Mock<AbstractBase>();
var notificationMock = entityMock.As<INotifyPropertyChanged>();
var propertyChangedMapper = new PropertyChangedMapper();
bool eventReceived = false;
propertyChangedMapper.MyPropertyChanged +=
(sender, eventArgs) =>
{
eventReceived = true;
};
propertyChangedMapper.Subscribe((AbstractBase)notificationMock.Object);
Assert.IsFalse(eventReceived);
notificationMock.Raise(e=>e.PropertyChanged += null,
new PropertyChangedEventArgs("Property1"));
Assert.IsTrue(eventReceived);
}
显然我可以在INotifyPropertyChanged
上使用模拟并且事件上升得很好,但在PropertyChangedMapper
内我需要将发件人转发到AbstractBase
,如果使用Mock<INotifyPropertyChanged>
则会失败
修改:
根据建议使用Mock.As<>()
似乎是正确的方法,上面唯一的问题是从notificationMock
升起的事件与对象的原始模拟无关。代码:
notificationMock.Object.PropertyChanged += (s, e) =>
{
var result = "this one is fired as it should";
};
mock.Object.PropertyChanged += (s, e) =>
{
var result = "this one is not called but is actually what I need";
};
notificationMock.Raise(e => e.PropertyChanged += null,
new PropertyChangedEventArgs("Property1"));
答案 0 :(得分:1)
考虑到你这样做的方式,没有事件的实现。界面本身就是“我有一个PropertyChanged事件”的合同。如果要引发该事件,则必须提供处理程序,即使它没有执行任何操作。在mocked类中实现PropertyChanged事件以引发事件。
更新:
尝试使用AbstractBase的代码:
public abstract class AbstractBase : INotifyPropertyChanged
{
public virtual event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
答案 1 :(得分:1)
您的PropertyChanged
事件是否被声明为virtual
事件?
public abstract class AbstractBase : INotifyPropertyChanged
{
public virtual event PropertyChangedEventHandler PropertyChanged;
}
(另请参阅:Jon Skeet on virtual events。)
答案 2 :(得分:1)
如果你让你的模拟器是多模拟的,你可能能够进行所需的演员表。由于Moq模拟通过泛型参数绑定到单个类型,因此必须显式逐步向模拟中添加其他接口或超类,然后在测试中使用最终产品。下面是一个如何执行此操作的简单示例。
var baseMock = new Mock<AbstractBase>();
var inpcMock = baseMock.As<INotifyPropertyChanged>();
// ...setup event...
propertyChangedMapper.Subscribe(inpcMock.Object);
// ... assertions ...