【问题标题】:How to support the runtime settings ThrowUnobservedTaskExceptions in unit tests (Visual Studio)?如何在单元测试(Visual Studio)中支持运行时设置 ThrowUnobservedTaskExceptions?
【发布时间】:2013-06-06 14:38:58
【问题描述】:

如何在单元测试(Visual Studio 2012 单元测试环境)中激活运行时设置 ThrowUnobservedTaskExceptions?

我尝试在单元测试项目中添加一个 App.config 文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <runtime>
    <ThrowUnobservedTaskExceptions enabled="true"/>
  </runtime>
</configuration>

很遗憾,这不起作用。以下单元测试应该失败,因为任务引发了未处理的异常。我怎样才能做到这一点?

[TestMethod]
public void TestMethod()
{
    Task.Factory.StartNew(() =>
    {
        throw new InvalidOperationException("Test");
    });

    // Sleep is necessary so that the task can finish.
    Thread.Sleep(100);
    // GC.Collect is necessary so that the finalizer of the 
    // Task is called which throws the exception.
    GC.Collect();
}

上面的单元测试只是重现我遇到的问题的简化示例。这些未处理的异常可能会在外部库中被调用,而自己无法处理这些异常。

【问题讨论】:

  • 您必须使用 Framework 4.5+ 并且不要忘记删除旧配置,以便复制新配置(带有ThrowUnobservedTaskExceptions 设置)。然后它应该工作。 VS2013u4.

标签: c# visual-studio unit-testing exception task


【解决方案1】:

我不确定如何导致您的测试失败,但以下代码至少导致测试输出中出现异常信息:

[TestInitialize]
public void SetThrowUnobservedTaskExceptions()
{
    Type taskExceptionHolder = typeof(Task).Assembly
        .GetType("System.Threading.Tasks.TaskExceptionHolder", false);
    if (taskExceptionHolder != null)
    {
        var field = taskExceptionHolder.GetField("s_failFastOnUnobservedException",
            BindingFlags.Static | BindingFlags.NonPublic);
        field.SetValue(null, true);
    }
}

看起来终结器线程的本机代码检查了一个无法通过反射设置的附加属性,这实际上导致进程终止。不过,我对此不是 100% 确定的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-19
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多