单元测试 .NET 事件调用
本文关键字:调用 事件 NET 单元测试 | 更新日期: 2023-09-27 17:56:32
我有一个静态类,它环绕 .NET 事件,如 UnhandledException
和 ProcessExit
(CurrentAppDomain 对象的),因此当调用者在类上调用 Initialize 时,它会为这些事件订阅我自己的处理程序,稍后调用者可以使用专用 API 添加自己的处理程序方法。(它是这样设计的,所以我能够在触发事件后控制处理程序的执行顺序)。
我的问题是:是否可以对这样的类进行单元测试?
例如,我想知道当抛出未处理的异常时,我的私有处理程序已执行。 问题是,当我抛出未经处理的异常时,这将是测试的"结果"(如果我错了,请纠正我)。如果我退出该过程,也会发生相同的情况。
我在想一个可能的解决方案可能涉及加载一个新的应用程序域,尽管我不知道这是否可能以及如何在技术上解决这个问题。
要测试UnhandledException
,您可以在新线程中抛出异常:
[TestMethod]
public void UnhandledTest()
{
using (var okEvent = new ManualResetEventSlim())
using (var notOkEvent = new ManualResetEventSlim())
{
UnhandledExceptionEventHandler handler = (o, e) =>
{
if (e.ExceptionObject is ApplicationException)
okEvent.Set();
else notOkEvent.Set();
};
AppDomain.CurrentDomain.UnhandledException += handler;
var thread = new Thread(() => { throw new ApplicationException(); });
thread.Start();
var result = EventWaitHandle.WaitAny(new[] { notOkEvent.WaitHandle, okEvent.WaitHandle }, 10000);
Assert.AreEqual(1, result);
AppDomain.CurrentDomain.UnhandledException -= handler;
}
}
这不会导致测试失败,因为测试框架仅在执行测试方法的线程上捕获异常。
另一方面,当当前进程退出时,ProcessExit
将被提出,因此测试框架很可能在那时已经关闭。因此,您必须在不同的进程中运行实际的测试代码。从单元测试方法开始,您将开始一个新的过程,它将运行测试的实质,并将测试结果传达回原始进程中的单元测试方法。
新流程只是一个单独的.exe项目。它所做的是附加到ProcessExit
,停止自身,并在ProcessExit
处理程序中检查一切是否正常,然后将结果传达回运行单元测试方法的进程。
您可以使用命令行进行从单元测试项目到 .exe 项目的通信,并使用某种 IPC(如临时文件或命名事件)进行通信。