单元测试时如何处理在其他线程中引发的异常?

时间:2009-05-21 00:00:19

标签: multithreading visual-studio unit-testing exception

使用Visual Studio Team Test进行测试时,会在结果中捕获并报告测试中未处理的异常。所以我很惊讶地看到测试托管进程(VSTestHost.exe)崩溃并显示系统崩溃对话框。

经过进一步调查,此崩溃是另一个线程中引发的未处理异常(更直接地,它是异步套接字回调)。事实上这样的事情会导致托管过程崩溃:

[TestMethod]
void Test()
{
    new Thread(() => { throw new Exception(); }).Start();
}

有什么建议我应该在那里做什么?

  • 我是否应该忍受它,说任何分发/签入的代码都应该至少测试一次,所以这样的事情很可能会被捕获?
  • 我是否应该尝试安装全局异常处理程序并在每种拆卸方法中检查其状态?
  • 或许已经存在帮助这个的东西?

6 个答案:

答案 0 :(得分:2)

您可以使用全局异常处理程序捕获AppDomain中所有未捕获的异常:

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new EventHandler(UnhandledExceptionHandler);

我认为它也适用于从其他线程抛出的异常

答案 1 :(得分:1)

您可以尝试设置AppDomain.CurrentDomain.UnhandledException并查看是否有效?我不知道它是如何与VS测试工具思想相互作用的

答案 2 :(得分:0)

通常我会尝试通过注入一个线程提供程序来避免在单元测试中启动线程,该线程提供程序在单元测试期间实际上不提供线程,而是同步执行。

当然,使用这种方法,你无法测试任何类型的潜在争用,或者两个并行运行的实际代码路径,但是有一个很好的论据,即这样的测试不是真正的单元测试。

当你测试两个同步线程时,你需要一个线程提供程序,它在线程结束时捕获异常并将它们报告为失败。

答案 3 :(得分:0)

一些想法:

  • 使用BackgroundWorker进行单元测试工作。 BackgroundWorker将自动捕获未处理的异常并在RunWorkerCompletedEventArgs的Error属性中报告它们。但是,您需要一种方法来阻止单元测试线程,直到BackgroundWorker完成工作。
  • 这个本身并不是一个不错的选择,甚至可能不适合您的测试目标。尽管如此,我想提一下。您可以回到使用legacyUnhandledExceptionPolicy在.NET 1.0和1.1中处理来自其他线程的未处理异常的方式。在.NET 2.0之前,线程中未处理的异常被忽略了。但是,在.NET 2.0中,它们实际上会导致应用程序终止。 legacyUnhandledExceptionPolicy设置允许您具有.NET 2.0之前的行为。

答案 4 :(得分:0)

我可以从C ++领域(如果知识可以被翻译)说的是,在给定线程中抛出的任何异常只能在该线程中被捕获。如果您的主应用程序启动了另外三个线程,那么您必须独立地从每个(现在4个)线程中捕获异常。没有办法在线程代码中实现“全局”异常处理程序。这与在操作系统中实现线程(和进程)的方式有关。

但就像我说的那样,我不知道这个逻辑与C#有多接近,因为它运行在像Java这样的虚拟机之上。

答案 5 :(得分:0)

在测试中有多个线程对我来说听起来不是 y 。有没有关于正在测试的逻辑,它必须有几个线程? 真的吗?

或者是否有一些正在测试的代码的协作者恰好是多线程的(如套接字)?如果是这种情况,你真的应该用那些合作者替换某种测试双打(模拟,存根或其他)。使用测试双打的额外好处是,如果它们是真实的,您可以更容易地控制他们的行为和响应。