When running this test:
[TestMethod]
[ExpectedException(typeof(SpecialException))]
public void Test1()
{
throw new NotImplementedException();
}
Visual Studio tells me why it fails:
Test method [...].Test1 threw exception System.NotImplementedException, but exception [...].SpecialException was expected. Exception message: System.NotImplementedException: The method or operation is not implemented.
But when I try to extend ExpectedExceptionBaseAttribute
(to expect for error code in SpecialException
) like that:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
class ExpectedSpecialException : ExpectedExceptionBaseAttribute
{
protected override void Verify(Exception exception)
{
SpecialException se = exception as SpecialException;
if (se == null)
{
RethrowIfAssertException(exception);
throw new Exception("SpecialException was expected but test method threw another one");
}
}
}
and use it like that:
[TestMethod]
[ExpectedSpecialException]
public void Test1()
{
throw new NotImplementedException();
}
VS produces a not very informative message:
Exception has been thrown by the target of an invocation.
All examples (1,2,3) of extending ExpectedExceptionBaseAttribute
I found on the internet have the same attempt to provide more info about failure in the thrown exception, but with no result.
Am I doing something wrong? Is there's a way to provide more information about such failed tests?
I don't think any of those posts you have referenced in your question has a proper implementation of a custom ExpectedException attribute. I 'm not saying that they are not valid solutions, I'm saying that they address different issues. I think what you are experiencing is a different problem which has not been addressed by any of those posts.
It seems that the the reason you are not getting a complete error message because of the null TestContext.
You can verify this by looking at the implementation of ExpectedExceptionAttribute. You can use the reflector and you can see that it internally use the TestContext.
If you look at the implementation of ExpectedExceptionBaseAttribute
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false,
Inherited = true)]
public abstract class ExpectedExceptionBaseAttribute : Attribute
{
protected internal TestContext TestContext { get; internal set; }
The TestContext sets internally at runtime, and cannot be injected into ExpectedSpecialException attribute. MSTest's ExpectedExceptionAttribute can access the TestContext which has been internally set by the test runner. Important to note that due to the lack of extensibility of the MSTest we cannot really access and set the TestContext as desired.
Not sure this would help but you can customize your exceptions and pin-point where the exception is thrown using an approach like this. I think this a better approach.