Testing whether certain exceptions are thrown by a test case is somewhat cumbersome. For each individual assertion, you have to write a try/catch clause for the method to be tested. Your test code looks like this:
try { String c1 = name.component(-42); fail("component() accepted invalid index"); } catch (NameIndexOutOfBoundsException nioob) { }
It would be nicer to write something like this:
assertException("component() accepted invalid index", name.component(-42), NameIndexOutOfBoundsException.class);
That's not possible, of course, because the method invocation is executed before assertException() gets a handle on it. Or, put shorter, it's not possible, because Java doesn't have blocks. We can emulate blocks, though, with the help of inner classes. Using a block lets us delay the method invocation and transfer it to the assertException() method.
I use an additional TestCaseBlock class to represent a block in Java. For each set of similar exception handling test cases, I write an inner class that inherits from TestCaseBlock (see example below).
If you want to use it, you have to add this class to junit.framework. In addition, you need to add this assertException() method to TestCase:
public void assertException(TestCaseBlock tcb, Class expectedEC) { tcb.run(expectedEC); }
Please note that it would be cleaner to add TestCaseBlock to junit.extensions. However, since I also had to change the TestCase class to add the assertException() method, I decided to be rude and to directly add to the core framework. If you want this test case block addition to stay strictly separated from the core framework, you can put the block class into junit.extensions and write a subclass of TestCase that adds the assertException() method. This subclass also goes into junit.extensions and becomes your test case superclass.
Back to the main thread. Now, your exception test cases may look like this:
public void testComponent() { // public String component(int i) throws NameIndexOutOfBoundsException; TestCaseBlock tcb= new TestCaseBlock("component() accepted invalid index") { public void test1() { String c1= fN0.component(1); } public void test2() { String c2= fN1.component(-1); } public void test3() { String c3= fN3.component(17); } public void test4() { String c4= fN5.component(3); } }; assertException(tcb, NameIndexOutOfBoundsException.class); }
Rather than this:
public void testComponent() { // public String component(int i) throws NameIndexOutOfBoundsException; try { String c1 = fN0.component(1); fail("component() accepted invalid index: " + String.valueOf(1)); } catch (NameIndexOutOfBoundsException nioob) { } try { String c2 = fN1.component(-1); fail("component() accepted invalid index: " + String.valueOf(-1)); } catch (NameIndexOutOfBoundsException nioob) { } try { String c3 = fN3.component(17); fail("component() accepted invalid index: " + String.valueOf(17)); } catch (NameIndexOutOfBoundsException nioob) { } try { String c4 = fN5.component(3); fail("component() accepted invalid index: " + String.valueOf(3)); } catch (NameIndexOutOfBoundsException nioob) { } }
Any comments or feedback (bugs...) welcome!