I need to write a unit test for the next function and I saw I can use [ExpectedException]
this is the function to be tested.
public static T FailIfEnumIs
While ExpectedException
cannot be used as-is to verify the exception's message, you could implement your own exception validation logic by inheriting from ExpectedExceptionBaseAttribute:
By implementing your own expected exception verification. you can specify additional information and requirements that the built-in methods of the ExpectedExceptionAttribute class cannot handle, such as the following:
- Verifying the state of the exception.
- Expecting more than one type of exception.
- Displaying a custom message when a wrong type of exception is thrown.
- Controlling the outcome of a negative test.
In your case, it could look something like this:
public sealed class ExpectedExceptionMessageAttribute : ExpectedExceptionBaseAttribute
{
readonly string _expectedMessage;
public ExpectedExceptionMessageAttribute(string expectedMessage)
{
_expectedMessage = expectedMessage;
}
protected override void Verify(System.Exception exception)
{
// Handle assertion exceptions from assertion failures in the test method
base.RethrowIfAssertException(exception);
Assert.IsInstanceOfType(exception, typeof(T), "wrong exception type");
Assert.AreEqual(_expectedMessage, exception.Message, "wrong exception message");
}
}
HAving said that, I would still be inclined to use the direct try
-catch
approach though as it is more specific in where exactly the exception is expected to be thrown:
public static void Throws(Action action, Predicate predicate = null)
where T : Exception
{
try
{
action();
}
catch (T e)
{
if (predicate == null || predicate(e))
{
return;
}
Assert.Fail($"Exception of type {typeof(T)} thrown as expected, but the provided predicate rejected it: {e}");
}
catch (Exception e)
{
Assert.Fail($"Expected exception of type {typeof(T)} but a different exception was thrown: {e}");
}
Assert.Fail($"No exception thrown, expected {typeof(T)}");
}