2

I tend to throw as many checked Exceptions up as possible: it declutters the code (and I regard checked Exceptions as a dubious aspect of Java). I tend to use them when "refining" code.. i.e. when it makes sense for the particular context.

This approach gets slightly complicated when overriding superclass/interface methods which don't throw the requisite Exception, and therefore I tend to do this:

@Override
public void close() {
    try {
        _close();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

where _close is a private method which does all the business.

The problem when it comes to JUnit, if you actually want to test something where an exception is thrown by _close() is that the resulting RuntimeException seems to be handled by JUnit in an "unconditional" way: it seems always to stop the test with a failure message... even if you actually catch and deal with it in a try .. catch!

There is a sort of "workaround" for this which I've found (the CUT class closes all its closeableComponents when it is closed):

@Test (expected = RuntimeException.class)
public void errorFlagShouldBeSetIfAnyCloseablesThrowExceptionWhenCUTCloses() throws Exception {
    Closeable spyCloseable = spy( new Closeable(){
        @Override
        public void close() throws IOException {
            throw new IOException( "dummy" );
        }});
    spyCUT.addCloseableComponent( spyCloseable );
    Exception blob = null;
    try{
        spyCUT.close();
    }catch( Exception e ){
        blob = e;
    }
    assertThat( spyCUT.getErrorFlag() ).isTrue();
    if( blob != null ){
        throw blob;
    }

I.e. if you don't have this expected setting you always get a test failure (because of the RuntimeException "ignoring" the try .. catch). But in order to satisfy the expected you then have to rethrow the RuntimeException at the end of the test...

... is there any way of varying JUnit's handling of RuntimeExceptions?

mike rodent
  • 14,126
  • 11
  • 103
  • 157

1 Answers1

1

Something must be wrong in your setup. JUnit does not have any such special handling for runtime exceptions.

I put together this MCVE; and it passes.

static class CUT {
    void close(Closeable _close) {
        try {
            _close.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

@Test
public void test() throws Exception {
    Closeable spyCloseable = Mockito.spy(new Closeable() {
        @Override
        public void close() throws IOException {
            throw new IOException("dummy");
        }
    });
    Exception blob = null;
    try {
        new CUT().close(spyCloseable);
        fail("should have thrown");
    } catch (Exception e) {
        blob = e;
    }
    assertThat(blob.getMessage(), is("java.io.IOException: dummy"));
}

It is not exactly what you have up there; but "close enough" in my mind.

Long story short: your answer is coming from some other place. I suggest: do the same as I did: create a true mcve; and work your way from there!

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Thanks very much. I ran your test and it's exactly as you say. Even if I just throw a new RuntimeException in the try .. catch in the test this exception is indeed caught by the catch. All very puzzling. This was done as a "Run as JUnit Test" in Eclipse. With my "real" project I am using gradle and running tests using the Eclipse STS Gradle plug-in. I'm also using AssertJ rather than Hamcrest... will have to "work my way" to the cause, as you say. – mike rodent Jan 05 '17 at 08:32
  • Thanks for the feedback/quick accept! Yes; I guess you have to go for step-by-step careful debugging now; as I dont see anything in that list you just gave that would explain what you are seeing. And for the record: I only ran this test within eclipse and the built-in "run as Junit" – GhostCat Jan 05 '17 at 08:37
  • @mike rodent I ran across similar issue. I am throwing IllegalStateException and If I use, catch (Exception e) then it works however if I explicitly catch it by catch (IllegalStateException e) then junit fails the test. Any ideas on this? – Destructor Jul 18 '18 at 19:12
  • 1
    btw, i just figured out MCVE - Minimal Complete Verifiable Example. – Sundar Rajan Jul 25 '21 at 15:19