14

I tried to implement solution based on answer How to handle exceptions raised in other threads when unit testing?, but I still don't understand what to do in the handler. Let's suppose I have a test:

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

I have and global initialization of all tests:

[AssemblyInitialize]
public static void AssemblyInitialize(TestContext context)
{
    AppDomain currentDomain = AppDomain.CurrentDomain;
    currentDomain.UnhandledException += currentDomain_UnhandledException;       
}

static void currentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    Exception ex = e.ExceptionObject as Exception;
    if (ex != null)
        Trace.WriteLine(ex);

        Assert.Fail("Unhandled Exception in thread.");
}

The problem is that Assert.Fail actually throws exception which is again caught by the currentDomain_UnhandledException and it causes MSTest to crash (stackoverflow?). I don't want to catch Assert.Fail, but I want to make the test failed. How to resolve it?

I know I could catch the exception and invoke it on test's main thread, but I need global solution for thousand tests. I don't want not to complicate every single test.

Community
  • 1
  • 1
Tomas Kubes
  • 23,880
  • 18
  • 111
  • 148
  • Could you simply check the exception object to see if it is the `Assert.Fail` exception and not do another `Assert.Fail`? – John Koerner Jul 11 '16 at 16:49

1 Answers1

0

Here is my approach to the problem:

        private List<(object sender, UnhandledExceptionEventArgs e)> _UnhandledExceptions;
        [TestInitialize()]
        public void Initialize()
        {
            _UnhandledExceptions = new List<(object sender, UnhandledExceptionEventArgs e)>();
            AppDomain.CurrentDomain.UnhandledException += (sender, e) => {
                _UnhandledExceptions.Add((sender, e));
            };
        }
        [TestCleanup()]
        public void Cleanup()
        {
            if (_UnhandledExceptions.Count != 0) Assert.Fail($"There were {_UnhandledExceptions.Count} unhandled Exceptions! <{string.Join(">," + Environment.NewLine + "<", _UnhandledExceptions.ToArray().Select(ev => ev.e.ExceptionObject))}>.");
        }

I choose Assert.fail over Assert.AreEqual(0 because it distracts from the actual problem. (Too bad there is no CollectionAssert.IsEmpty() method, that actually prints the collection on error.

htho
  • 1,549
  • 1
  • 12
  • 33