Visual Studio Test can check for expected exceptions using the ExpectedException attribute. You can pass in an exception like this:
[TestMethod]
[ExpectedExc
Just an opinion, but I would say the error text:
Note that the first option should let you test multiple languages, given the ability to run with a locale.
As for multiple exceptions, I'm from C++ land, where creating loads and loads of exceptions (to the point of one per 'throw' statement!) in big heirachies is acceptable (if not common), but .Net's metadata system probably doesn't like that, hence that advice.
The ExpectedException Message argument does not match against the message of the exception. Rather this is the message that is printed in the test results if the expected exception did not in fact occur.
I think you can just do an explicit try-catch in your test code instead of relying on the ExpectedException attribute to do it for you. Then you can come up with some helper method that will read the resource file and compare the error message to the one that comes with the exception that was caught. (of course if there wasn't an exception then the test case should be considered a fail)
I wonder if NUnit is moving down the path away from simplicity... but here you go.
New enhancements (2.4.3 and up?) to the ExpectedException attribute allow you more control on the checks to be performed on the expected Exception via a Handler method. More Details on the official NUnit doc page.. towards the end of the page.
[ExpectedException( Handler="HandlerMethod" )]
public void TestMethod()
{
...
}
public void HandlerMethod( System.Exception ex )
{
...
}
Note: Something doesn't feel right here.. Why are your exceptions messages internationalized.. Are you using exceptions for things that need to be handled or notified to the user. Unless you have a bunch of culturally diverse developers fixing bugs.. you shouldn't be needing this. Exceptions in English or a common accepted language would suffice. But in case you have to have this.. its possible :)
If you switch over to using the very nice xUnit.Net testing library, you can replace [ExpectedException] with something like this:
[Fact]
public void TestException()
{
Exception ex = Record.Exception(() => myClass.DoSomethingExceptional());
// Assert whatever you like about the exception here.
}
I came across this question while trying to resolve a similar issue on my own. (I'll detail the solution that I settled on below.)
I have to agree with Gishu's comments about internationalizing the exception messages being a code smell.
I had done this initially in my own project so that I could have consistency between the error messages throw by my application and in my unit tests. ie, to only have to define my exception messages in one place and at the time, the Resource file seemed like a sensible place to do this since I was already using it for various labels and strings (and since it made sense to add a reference to it in my test code to verify that those same labels showed in the appropriate places).
At one point I had considered (and tested) using try/catch blocks to avoid the requirement of a constant by the ExpectedException attribute, but this seemed like it would lead to quite a lot of extra code if applied on a large scale.
In the end, the solution that I settled on was to create a static class in my Resource library and store my exception messages in that. This way there's no need to internationalize them (which I'll agree doesn't make sense) and they're made accessible anytime that a resource string would be accessible since they're in the same namespace. (This fits with my desire not to make verifying the exception text a complex process.)
My test code then simply boils down to (pardon the mangling...):
[Test,
ExpectedException(typeof(System.ArgumentException),
ExpectedException=ProductExceptionMessages.DuplicateProductName)]
public void TestCreateDuplicateProduct()
{
_repository.CreateProduct("TestCreateDuplicateProduct");
_repository.CreateProduct("TestCreateDuplicateProduct");
}