h bob
h bob

Reputation: 3780

NUnit assertion that a certain exception is not thrown

NUnit has these:

Exception Assert.Throws<TActual>(TestDelegate)        // code must throw a TActual
void Assert.DoesNotThrow(TestDelegate)                // code mustn't throw anything

It does not have this:

Exception Assert.DoesNotThrow<TActual>(TestDelegate)  // code musn't throw a TActual, but 
                                                      // is allowed to throw anything else

How could I create that, or use the constraints mechanism to do that?

Upvotes: 2

Views: 1169

Answers (2)

Zortaniac
Zortaniac

Reputation: 141

Maybe you can implement it like this:

public static class CustomAssert
{
    public static void DoesNotThrow<T>(TestDelegate code) where T : Exception
    {
        DoesNotThrow<T>(code, string.Empty, null);
    }
    public static void DoesNotThrow<T>(TestDelegate code, string message, params object[] args) where T : Exception
    {
        Assert.That(code, new ThrowsNotExceptionConstraint<T>(), message, args);
    }
}

public class ThrowsNotExceptionConstraint<T> : ThrowsExceptionConstraint where T : Exception
{
    public override string Description
    {
        get { return string.Format("throw not exception {0}", typeof(T).Name); }
    }

    public override ConstraintResult ApplyTo<TActual>(TActual actual)
    {
        var result = base.ApplyTo<TActual>(actual);

        return new ThrowsNotExceptionConstraintResult<T>(this, result.ActualValue as Exception);
    }

    protected override object GetTestObject<TActual>(ActualValueDelegate<TActual> del)
    {
        return new TestDelegate(() => del());
    }

    class ThrowsNotExceptionConstraintResult<T> : ConstraintResult where T : Exception
    {
        public ThrowsNotExceptionConstraintResult(ThrowsNotExceptionConstraint<T> constraint, Exception caughtException)
            : base(constraint, caughtException, !(caughtException is T)) { }

        public override void WriteActualValueTo(MessageWriter writer)
        {
            if (this.Status == ConstraintStatus.Failure)
                writer.Write("throws exception {0}", typeof(T).Name);
            else
                base.WriteActualValueTo(writer);
        }
    }
}

and call it like

CustomAssert.DoesNotThrow<TException>(() => { throw new TException(); });

Im not using NUnit, so maybe there is a better aproach.

Upvotes: 3

Valentin Sky
Valentin Sky

Reputation: 132

If you don't find any cleaner solution, you could do the following.

[Test]
public void TestThatMyExceptionWillNotBeThrown()
{
    try
    {
        TheMethodToTest();

        // if the method did not throw any exception, the test passes
        Assert.That(true);
    }
    catch(Exception ex)
    {
        // if the thrown exception is MyException, the test fails
        Assert.IsFalse(ex is MyException);
    }
}

Upvotes: 1

Related Questions