简体   繁体   中英

Implementing Unhandled Exception Handler in C# Unit Tests

I've got some tests and they rely heavily on some shared code that I can't modify. This shared code throws an exception sometimes and I want to be able to handle all uncaught instances of this exception without wrapping every call to the shared code in a try catch (there are years of tests here).

I also want to be able to re-throw the exceptions that aren't of the type that I'm looking for.

I've tried

public void init() 
{
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    Logger.Info("Caught exception");
    throw (Exception)e.ExceptionObject;
}

But it appears that the stock unit test framework ( Microsoft.VisualStudio.QualityTools.UnitTestsFramework ) is doing something with the AppDomain and preventing me from replacing its UnhandledException handler or I'm simply not understanding how the unit test framework handles AppDomain s (highly likely).

Anyone have any suggestions?

Try attaching to the AppDomain.CurrentDomain.FirstChanceException event. Per Microsoft's documentation:

Occurs when an exception is thrown in managed code, before the runtime searches the call stack for an exception handler in the application domain.

In other words, you can catch it before the Unit Test Framework does. More info here .

Too bad there has to be a workaround for this, but below is mine. We use unhandled exception handler in the application, which was triggered by some error. Unfortunately the unhandled exception was swallowed by the test framework during unit testing.

using System;
using Xunit;
using System.Threading;

public class MyTests : IDisposable
{
    private UnhandledExceptionEventArgs _unhandledException = null;
    public MyTests()
    {
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
    }

    public void Dispose()
    {
        Assert.Null(_unhandledException);
    }

    private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        _unhandledException = e;
    }

    //Example from : https://github.com/xunit/xunit/issues/157
    [Fact]
    public void TestExceptionInBackgroundThread()
    {
        Thread t = new Thread(() =>
        {
            throw new InvalidOperationException();
        });
        t.Start();
        t.Join();
    }
}

输出

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM