Unable to test exception with junit

2019-07-02 01:52发布

I have a method which contains a try-catch block and I don't know how to make my test pass...

Here is my code:

public class ClassToTest {
    public void loadFileContent() {
        try {
            InputStream fileStream = fileLoader.loadFileContent();
            fileContentReader = new BufferedReader(new InputStreamReader(fileStream));
        } catch(CustomException ce) {
            logger.log(Level.SEVERE, "Error message")
        }
    }
}

public class TestClassToTest {
    @Test
    (expected = CustomException.class)
    public void testCustomException() throws Exception {
        loadFileContent();
    }
}

The only thing I want to do when the exception is thrown is to log it, and that all works great, however, how can I create a test that shows that it works?

I tried to capture console output and

assertTrue(consoleOutput.contains("logMessgae") 

and that worked as long as I ran only that specific test case, but it did not work when I ran it in my test suite.

4条回答
相关推荐>>
2楼-- · 2019-07-02 02:02

If you're trying to test that CustomException is thrown under certain conditions, then you should be testing the code that throws the exception, rather than the code that catches it. In your example, I'm guessing that your undefined "fileLoader" is what you're expecting to throw the exception?

If you're trying to test that the exception is caught and things continue to run smoothly, then you need to redesign ClassToTest so that a mock implementation of the potentially exception throwing class can be injected. That mock implementation would always throw the exception. Then you can run through ClassToTest in your test and assert whatever condition indicates that it handled the exception properly.

查看更多
走好不送
3楼-- · 2019-07-02 02:14

Your code is untestable without having a mock file in place. You can make this code more testable by mocking out external dependencies and using dependency injection (i.e. via guice).

查看更多
你好瞎i
4楼-- · 2019-07-02 02:20

I think the right way to do this is pass your logger into your class, and if you're using a mocking framework like Mockito, you can verify your logger with verify:

ClassToTest myInstance = new ClassToTest(myLogger);

// then, in your unit test
verify(myLogger).log("my log message")

the key here is passing in your dependencies so you can then verify interactions with them.

查看更多
孤傲高冷的网名
5楼-- · 2019-07-02 02:23

The contract of the method is to catch CustomException and log "Error Message" to an external component : the logger. You should thus create a mock logger, give it to the ClassToTest instance, test the method and verify that the mock logger has been called with the aright arguments.

I personnally use EasyMock (and its "classextension" extension) to mock concrete classes, but there are other mock frameworks. Read http://easymock.org/EasyMock3_0_Documentation.html for information about EasyMock and mocking in general.

查看更多
登录 后发表回答