3

In unit tested code I often have multiple checks on the arguments on any method before the actual "work" of the method is begun:

public void DoSomething(string test)
{
   if (string.IsNullEmptyOrWhiteSpace(test))
   {
       throw new ArgumentException("Test must not be empty", "test");
   }
}

In my corresponding test for this method I'll do the following:

[Test]
[ExpectedException(typeof(ArgumentException),
    Message = "Parameter name: test",
    MatchType = MatchType.Contains)]
public void TestNullInput()
{
    var classToTest = new ClassToTest();
    classToTest.DoSomething(null);
}

I'm thinking that this is quite a bad way to go about doing the test, however, as it relies on a specific named parameter (which does not necessarily hold true after any refactoring), as well as the format of the message of an ArgumentException.

Another option might be to create a custom exception for this, some form of "TestWasNullOrEmptyException", but this also seems fairly awkward, as there will be many many different exceptions throughout the solution, each used to indicate only the absence/invalidity of a parameter.

I am wondering if anyone else has dealt with this issue, and whether I'm simply going about my input validation tests the wrong way of it there's a more elegant solution.

EDIT: This is C# code, and I'm using NUnit/Rhino Mocks.

1 Answer 1

1

What test framework are you using? Looks similar to junit (ExpectedException, MatchType), but the square bracket syntax is new to me. Is this c#'s NUNIT?

I use junit 4's ExpectedException in a programatic way. Therefore, I can set a lot of attributes of the Exception, like thrown.expectMessage(startsWith("What"));. For me, this is sufficiently flexible.

Another option might be to create a custom exception for this, some form of "TestWasNullOrEmptyException"

That does not seem to be good idea. With that argument, you could never use a general exception. But abstraction is good, to cope with complexity. In your case, thousands of new Exception classes, that also have to be caught and handled somewhere, would produce the complexity that can better be dealt with via more abstract exceptions, like ArgumentException.

6
  • Oops, probably should have specified that's it's NUnit and C#! There's not as much flexibility with the ExpectedException attribute in C#, but I guess I could try{}catch{} and Assert things manually, which would be an equivalent approach.
    – Ed James
    Feb 23, 2012 at 12:40
  • yup, I suspected NUnit. Maybe NUnit's ExpectedException is equally powerful to junit's one?
    – DaveFar
    Feb 23, 2012 at 12:42
  • Sorry, I was editing that comment for some more detail. The ExpectedException is fairly constrained, as far as I can tell, with only a single match option and a small number of matching types (StartWith, Contains, Regex, and Exact).
    – Ed James
    Feb 23, 2012 at 12:44
  • If you have a unit test per argument, then do you really need to test the exception's message contents? Feb 23, 2012 at 13:02
  • 1
    @PeterSmith Yes, as if you have multiple arguments being checked and they all return an ArgumentException, when you refactor you code and inadvertently move an argument call lower down the list of arguments to check your test might still pass even though what you were testing actually fails. I actually came across this situation not long ago, which initiated the whole "checking the error message" thing!
    – Ed James
    Feb 23, 2012 at 21:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.