gpt4 book ai didi

c# - 使用反射在 C# 中引发事件的单元测试

转载 作者:可可西里 更新时间:2023-11-01 08:21:40 24 4
gpt4 key购买 nike

我想测试设置某个属性(或更一般地说,执行某些代码)是否会在我的对象上引发某个事件。在这方面,我的问题类似于 Unit testing that an event is raised in 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);
}

如您所见,我的问题在于为此事件创建适当类型的 Delegate。委托(delegate)除了调用 incrementer 之外什么都不做。

由于 C# 中的所有语法糖浆,我对委托(delegate)和事件如何真正工作的概念有点模糊。这也是我第一次涉足反射(reflection)。缺少的部分是什么?

最佳答案

我最近写了一系列关于对发布同步和异步事件的对象进行事件序列单元测试的博文。这些帖子描述了单元测试方法和框架,并提供了带有测试的完整源代码。

我描述了“事件监视器”的实现,它允许编写更干净的事件排序单元测试,即摆脱所有困惑的样板代码。

使用我文章中描述的事件监视器,可以像这样编写测试:

var publisher = new AsyncEventPublisher();

Action test = () =>
{
publisher.RaiseA();
publisher.RaiseB();
publisher.RaiseC();
};

var expectedSequence = new[] { "EventA", "EventB", "EventC" };

EventMonitor.Assert(publisher, test, expectedSequence);

或者对于实现 INotifyPropertyChanged 的​​类型:

var publisher = new PropertyChangedEventPublisher();

Action test = () =>
{
publisher.X = 1;
publisher.Y = 2;
};

var expectedSequence = new[] { "X", "Y" };

EventMonitor.Assert(publisher, test, expectedSequence);

对于原始问题中的案例:

MyClass myObject = new MyClass();
EventMonitor.Assert(myObject, () => { myObject.Width = 42; }, "Width");

EventMonitor 完成所有繁重的工作,并将运行测试(操作)并断言事件按预期顺序 (expectedSequence) 引发。它还会在测试失败时打印出很好的诊断消息。在后台使用反射和 IL 来使动态事件订阅工作,但这一切都被很好地封装了,所以只需要像上面这样的代码来编写事件测试。

在描述问题和方法的帖子中有很多细节,还有源代码:

http://gojisoft.com/blog/2010/04/22/event-sequence-unit-testing-part-1/

关于c# - 使用反射在 C# 中引发事件的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2567047/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com