ExpectedExceptionAttribute (NUnit 2.0 plus Updates)
This is the way to specify that the execution of a test will throw an exception. This attribute has a number of positional and named parameters, which we will discuss in separate sections according to the purpose they serve.
Specifying the Expected Exception Type
The original attribute, introduced with NUnit 2.0 took a single argument giving the exact type of the expected exception. For example...
[ExpectedException( typeof( ArgumentException ) )] public void TestMethod() { ...
Beginning with NUnit 2.2.4, it became possible to specify the type of exception as a string, avoiding the need for a reference to the defining assembly...
[ExpectedException( "System.ArgumentException" ) )] public void TestMethod() { ...
The above two examples function identically: the test only succeeds if a System.Argument exception is thrown.
Specifying the Expected Message
NUnit 2.1 introduced a constructor with a second argument, specifying the exact text of the message property of the exception. After NUnit 2.2.4, the same extension was made to the constructor taking a string argument. With NUnit 2.4, these arguments are marked obsolete, and a named parameter is provided instead...
// Obsolete form: [ExpectedException( typeof( ArgumentException ), "expected message" )] [ExpectedException( "System.ArgumentException", "expected message" )] // Prefered form: [ExpectedException( typeof( ArgumentException ), ExpectedMessage="expected message" )] [ExpectedException( "System.ArgumentException", ExpectedMessage="expected message" )]
With NUnit 2.4, it is possible to specify additional tests on the exception message, beyond a simple exact match. This is done using the MatchType named parameter, whose argument is an enumeration, defined as follows:
public enum MessageMatch { /// Expect an exact match Exact, /// Expect a message containing the parameter string Contains, /// Match the regular expression provided as a parameter Regex, /// Expect a message starting with the parameter string StartsWith }
The following example is for a test that passes only if an ArgumentException with a message containing "unspecified" is received.
[ExpectedException( typeof( ArgumentException), ExpectedMessage="unspecified", MatchType=MessageMatch.Contains )] public void TestMethod() { ...
If MatchType is not specified, an exact match is used as before.
Specifying a Custom Error Message
With NUnit 2.4, it is possible to specify a custom message to be displayed if the ExpectedException attribute is not satisfied. This is done through the UserMessage named parameter...
[ExpectedException( typeof( ArgumentException ), UserMessage="Custom message" )] public void TestMethod() { ...
Handling the Exception in Code
If the processing required for an exception is too complex to express in the attribute declaration, the normal practice is to process it in the test code using a try/catch block. As an alternative, NUnit 2.4 allows designating a method that will be called to process the exception. This is particularly useful when multiple exceptions need to be processed in the same way.
An common exception handler may be designated by implementing the IExpectExceptionInterface, which is defined as follows...
public interface IExpectException { void HandleException( System.Exception ex ); }
The exception handler is only called for methods marked with the ExpectedException attribute. If all checks - including the type of the exception - are to be performed in code, the attribute may be specified without any arguments in order to indicate that an exception is expected.
An handler may be designated for a particular method using the Handler named parameter.
[ExpectedException( Handler="HandlerMethod" )] public void TestMethod() { ... } public void HandlerMethod( System.Exception ex ) { ... }
This technique may be used without implementing IExpectException or in combination with it. In the latter case, the designated handler applies to any method that specifies it, while the normal exception handler applies to any other methods that specify an ExpectedException.
However it is specified, the handler method should examine the exception and Assert on whatever properties are relevant. Any resulting failure message will then be consistent in format with other assertions performed in the tests.
Example:
namespace NUnit.Tests { using System; using NUnit.Framework; [TestFixture] public class SuccessTests { [Test] [ExpectedException(typeof(InvalidOperationException))] public void ExpectAnExceptionByType() { /* ... */ } [Test] [ExpectedException("System.InvalidOperationException")] public void ExpectAnExceptionByName() { /* ... */ } } }
Imports System Imports Nunit.Framework Namespace Nunit.Tests <TestFixture()> Public Class SuccessTests <Test(), ExpectedException(GetType(Exception))> Public Sub ExpectAnExceptionByType() ' ... End Sub <TestFixture()> Public Class SuccessTests <Test(), ExpectedException("System.Exception")> Public Sub ExpectAnExceptionByName() ' ... End Sub End Class End Namespace
#using <Nunit.Framework.dll> using namespace System; using namespace NUnit::Framework; namespace NUnitTests { [TestFixture] public __gc class SuccessTests { [Test] [ExpectedException(__typeof(InvalidOperationException))] void ExpectAnExceptionByType(); [Test] [ExpectedException(S"SystemInvalidOperationException")] void ExpectAnExceptionByName(); }; } #include "cppsample.h" namespace NUnitTests { // ... }