我想测试设置某个属性(或更一般地,执行一些代码)会在我的对象上引发某个事件.在这方面我的问题类似于单元测试,在C#中引发一个事件,但我需要很多这些测试而且我讨厌样板.所以我正在寻找一种更通用的解决方案,使用反射.
理想情况下,我想做这样的事情:
[TestMethod]
public void TestWidth() {
MyClass myObject = new MyClass();
AssertRaisesEvent(() => { myObject.Width = 42; }, myObject, "WidthChanged");
}
Run Code Online (Sandbox Code Playgroud)
为了实现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);
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我的问题在于Delegate为此事件创建适当的类型.代理除了调用之外什么都不做incrementer.
由于C#中的所有语法糖浆,我对委托和事件如何工作的概念有点模糊.这也是我第一次涉足反思.丢失的部分是什么?
想知道这是否是用事件测试结果的正确方法.
我正在开发一个应用程序,当Save正在进行/完成时它会触发事件.
为了测试它,我想出了以下内容(制作场景).我想知道这是不是你这样做的方式:
[Test]
public void Save_WhenCalled_IsSuccessfull()
{
//Arrange
var customerService= new CustomerService();
customerService.OnSaved += (sender, args) =>
{
Assert.IsTrue(args.HasSaved);
};
customerService.Save(new Customer {Id=1,Name="Jo"});
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢的是,如果你明白我的意思,我之前就断言了.
我希望断言在视觉上最后.顺便说一下,上面的工作很好,但不太开心.
有什么建议?