我想测试设置某个属性(或更一般的说,执行一些代码)是否会在我的对象上触发某个事件。在这方面,我的问题类似于在C#中单元测试引发事件的问题,但是我需要很多这样的测试而且我讨厌样板文件。因此,我正在寻找一种更通用的解决方案,使用反射。
理想情况下,我想这样做:
[TestMethod]
public void TestWidth() {
MyClass myObject = new MyClass();
AssertRaisesEvent(() => { myObject.Width = 42; }, myObject, "WidthChanged");
}
为了实现AssertRaisesEvent
,我已经做到了这一步:
private void AssertRaisesEvent(Action action, object obj, string eventName)
{
EventInfo eventInfo = obj.GetType().GetEvent(eventName);
int raisedCount = 0;
Action incrementer = () => { ++raisedCount; };
Delegate handler = /* what goes here? */;
eventInfo.AddEventHandler(obj, handler);
action.Invoke();
eventInfo.RemoveEventHandler(obj, handler);
Assert.AreEqual(1, raisedCount);
}
正如你所看到的,我的问题在于创建适合此事件的委托
。该委托除了调用incrementer
之外不应执行任何操作。
由于C#中存在大量的语法糖,导致我对委托和事件的真实工作原理的概念有些模糊。这也是我第一次尝试反射。缺少什么部分?