From: Tom Anderson on
On Wed, 19 May 2010, Patricia Shanahan wrote:

> Lew wrote:
>> Rhino wrote:
>>
>> and failed to acknowledge Daniel Pitts, who said:
>>>>> public void testParseException() {
>>>>> try {
>>>>> myObj.getRGB("Bad value!");
>>>>> fail("Bad value did not cause exception!");
>>>>> } catch(IllegalArgumentException e) {
>>>>> // Success!
>>>>> }
>>>>> }
>>>>>
>>>>> public void testGoodParse() {
>>>>> assertEqual(white, myObj.getRGB("FFFFFF"));
>>>>> }
>>
>> Rhino:
>>>> Thank you VERY much for the speedy AND accurate answer! It never
>>>> occurred to me to try that! It solves my problem very simply and
>>>> elegantly. :-)
>>
>> Tom Anderson wrote:
>>> Not as elegantly as my solution!
>>
>> Indeed. As someone who is just now getting used to JUnit 4 and who loves,
>> nay, adores annotations, I found tom's response exceedingly enlightening.
>
> I have a slight problem with using the annotation approach alone. It can
> only check for a throw of appropriate type. It cannot check other
> features of the thrown object, such as its message or a wrapped
> exception. As far as I can tell, a catch block is the only way to fully
> test if the interface promises anything beyond a throw type.

Very true. Daniel's point about not being able to make assertions about
the throwing object after the throw is also a good one. I suppose i'd
retreat slightly and say the expected exception method is appropriate when
you just want to check that the right exception is thrown, because it's
easy, it makes the intent clear, and it gives you a nice error message,
but if you want to do anything more, it's no use.

It also runs the risk of silently letting bugs pass in situations like
this:

@Test(expected=IndexOutOfBoundsException.class)
public void testGetThrowsExceptionForBadIndex() {
List<String> l = new MyList();
l.add("hello");
l.get(1);
}

This is written to check that get correctly throws an exception - but if
add incorrectly throws an exception, it will still pass.

So now i'm thinking about retreating even further.

tom

--
OK, mostly because of Tom, but not only because of his bloody irritating
character and songs.
From: Arne Vajhøj on
On 18-05-2010 17:03, Tom Anderson wrote:
> On Tue, 18 May 2010, Rhino wrote:
>> I can easily invoke the method with a value that will cause the
>> exception to be thrown and I can catch it with a standard try/catch
>> block. I can also put code in my catch block to make sure that JUnit
>> reports the error from the Exception in the method being tested. I end
>> up with this test which correctly reports the IllegalArgumentException
>> within the JUnit window:
>>
>> try {
>> Color actualRGBColor = colorConversionUtils.getRGBColor("FFFFFFA");
>> Color expectedRGBColor = new Color(255, 255, 255);
>> assertTrue("Actual color, " + actualRGBColor + ", does not equal expected
>> color, " + expectedRGBColor, actualRGBColor.equals(expectedRGBColor));
>>
>> }
>> catch (IllegalArgumentException ia_excp) {
>> assertionFailedError = new AssertionFailedError(ia_excp.getMessage());
>> assertionFailedError.initCause(ia_excp);
>> throw assertionFailedError;
>> }
>>
>> So far, so good.
>
> No, not good, this is completely wrong.
>
> You want this:
>
> @Test(expected=IllegalArgumentException.class)
> public void getRGBColorThrowsExceptionOnBadInput() {
> colorConversionUtils.getRGBColor("FFFFFFA");
> }

If he can upgrade from JUnit 3 to 4.

Otherwise the fail method as show by Daniel Pitt must be the
solution.

JUnit 4 is relative old now, so I can not see any reasons not
to upgrade (at least not for a project where the work to convert
is not a problem in itself).

Arne