nunit: Cannot catch AssertionException

Executing an NUnit assertion within a try block results in it not being captured by the catch block and it fails the test.

The following test fails due to the Assert.False(true) and does not throw the NotImplementedException:

using System;
using NUnit.Framework;

namespace ApiTests
{
    [TestFixture]
    public class Class1
    {

        [Test]
        public void ATest()
        {
            try
            {
                Assert.False(true);
            }
            catch (Exception e)
            {
                throw new NotImplementedException("whoops", e);
            }
            Assert.True(true);
        }
    }
}

While looking through #2007 I found this workaround:

using System;
using NUnit.Framework;
using NUnit.Framework.Internal;

namespace ApiTests
{
    [TestFixture]
    public class Class1
    {
        [Test]
        public void ATest()
        {
            using (new TestExecutionContext.IsolatedContext())
            {
                try
                {
                    Assert.IsTrue(false);
                }
                catch (Exception e)
                {
                    throw new NotImplementedException("whoops", e);
                }
            }
            Assert.True(true);
        }
    }
}

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 4
  • Comments: 15 (10 by maintainers)

Most upvoted comments

You might take a look at the XML generated for your test. I suspect you’ll find something like

<assertions>
    <assertion>...</assertion>
    <assertion>...</assertion>
</assertions>

where the first assertion element is for the failure and the second is for the assertion thrown. This won’t matter to you if you are using a legacy runner that doesn’t read that information but if you use a runner that understands the new elements, you will see both the failure and the error reported.

I do see what you are missing from NUnit… we give you the ability to repeat a test until it succeeds using [Retry] as well as the ability to repeat a single assertion using .After. We don’t currently give you the ability to repeat a series of assertions until they all pass.

NUnit has always considered the use of an AssertionException as an implementation detail. The same goes for IgnoreException, SuccessExeption and InconclusiveException. It’s certainly true that it’s an implementation detail used in common with many (but not all) other test frameworks. Over the years, when I’ve seen folks catching an AssertionException, either in an online forum or at one of my client shops, I’ve told them “Don’t do that because there is no guarantee the implementation will remain the same.”

As explained in more detail in #2007, NUnit no longer even throws an assertion exception upon every assertion failure. In your case it does and I believe you are incorrect in thinking it is not being thrown. However, distinct from earlier releases, the exception is used only to terminate execution, not to report the failure. The failure is reported before the exception is thrown.

We can certainly talk about ways to improve NUnit to make it easier to do what you are trying to do, but going back to the old implementation that relies on an exception is really not an option. That’s because NUnit now needs to be able to report a failure without terminating execution, for example when you use Multiple Asserts or Warning messages.

One way to handle at least some situations is to use the DelayedConstraint. You would have to check to see if it meets your needs.

I suggest you write some pseudocode that you wish you could use and we’ll talk about ways to make that happen.

The most fundamental question about this code is “Why do you want to do this?” As it stands, the code is only an example but the only reason I can see for catching AssertionException is if you are testing NUnit itself.

In fact, in the code given, the exception will be thrown and you should be able to trace it in the debugger. However, catching the exception will not prevent the test from failing as you appear to expect.

I’ll keep this open for now in case you have more info to add but it doesn’t look like a bug to me so far, just a mismatch between what NUnit does internally and what you expected.