Junit 4.12 Issue testing exception

2019-03-06 00:15发布

I have a simple method trying to fetch some file. I would like to test when the file is none existent and this is where my problem begins. The test keeps failing.

The method is something like :

public Configuration populateConfigs(Configuration config) throws UnRetriableException {

    try {
                 ....

    } catch (IOException | ConfigurationException e) {
        log.error(" getConfiguration : ", e);
        throw new UnRetriableException(e);
    }

    throw new UnRetriableException("problem getting config files.");
}

In my tests I have tried two separate solutions without success.

  1. Using the new style as suggested in the SO solution

    @Rule
    public ExpectedException exception = ExpectedException.none();
    @Test
    public void testPopulateConfigurationMissing() throws Exception {
    
        exception.expect(UnRetriableException.class);
        DefaultConfigHandler configurationFactory = new DefaultConfigHandler(testDirectory, testFileThatIsNonExistant);
        Configuration configuration = configurationFactory.populateConfiguration(systemConfig);
    
    }
    
  2. For method two which is just how I used to know exceptions are tested.

    @Test(expected = UnRetriableException.class)
    public void testPopulateConfigurationMissing() throws Exception {
    
        DefaultConfigHandler configurationFactory = new  DefaultConfigHandler(testDirectory, testFileThatIsNonExistant);
        Configuration configuration = configurationFactory.populateConfiguration(systemConfig);
    
    }
    

The exception is actually thrown as shown below :

com.caricah.iotracah.exceptions.UnRetriableException: java.nio.file.NoSuchFileException: world/over
at com.caricah.iotracah.system.handler.impl.DefaultConfigHandler.populateConfiguration(DefaultConfigHandler.java:137)
at com.caricah.iotracah.system.handler.impl.DefaultConfigHandlerTest.testPopulateConfigurationMissingDirectory(DefaultConfigHandlerTest.java:137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)

Hence my question, what else do I need to do to make the test pass?

Ofcourse without using the junit3 way of catching the exception.

1条回答
放荡不羁爱自由
2楼-- · 2019-03-06 01:06

Just tested it, works as expected... The class...

public class SomeClass {

    public void someMethod(String someParameter) throws SomeException {
        throw new SomeException("Yep, really a SomeException");
    }

}

The exception...

public class SomeException extends Exception {

    public SomeException(String message) {
        super(message);
    }

}

And the test class, both tests work exactly as expected:

public class TestSomeClass {

    @Rule
    public ExpectedException exception = ExpectedException.none();

    @Test
    public void testSomeMethodWithRule() throws SomeException {
        exception.expect(SomeException.class);

        new SomeClass().someMethod("something");
    }

    @Test(expected=SomeException.class)
    public void testSomeMethodWithExpected() throws SomeException { 
        new SomeClass().someMethod("something");
    }
}

After downloading your project (see comment), I don't know for sure why, but I know what the problem is: It's the extends Testcase. I assume that this somehow leads to a different way of executing your unit tests (stacktrace implies that they get executed with the JUnit38ClassRunner then). Remove it (you don't need it anyway) and instead call your asserts with Assert.<something>, for example Assert.assertTrue(...). (You can use static imports for that, too, so you don't have to write the Assert part). That solves your problem and all tests succeed.

Another possibility seems to be to keep the extends TestCase and use @RunWith(BlockJUnit4ClassRunner.class), which also fixes your problem, so probably the default Runner for a TestCase isn't up to it.

查看更多
登录 后发表回答