Java 无法使用junit测试异常

Java 无法使用junit测试异常,java,exception,testing,junit,Java,Exception,Testing,Junit,我有一个包含try-catch块的方法,我不知道如何使我的测试通过 这是我的密码: public class ClassToTest { public void loadFileContent() { try { InputStream fileStream = fileLoader.loadFileContent(); fileContentReader = new BufferedReader(new InputStre

我有一个包含try-catch块的方法,我不知道如何使我的测试通过

这是我的密码:

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();
    }
}
当抛出异常时,我想做的唯一一件事就是记录它,并且所有的工作都很好,但是,我如何创建一个测试来证明它是工作的呢

我试图捕获控制台输出并

assertTrue(consoleOutput.contains("logMessgae") 

只要我只运行那个特定的测试用例,它就工作了,但当我在测试套件中运行它时,它就不工作了。

如果没有模拟文件,您的代码是不稳定的。通过模拟外部依赖项并使用依赖项注入(即via),可以使此代码更易于测试。

该方法的契约是捕获CustomException并将“错误消息”记录到外部组件:记录器。因此,您应该创建一个模拟记录器,将其提供给ClassToTest实例,测试该方法并验证是否使用正确的参数调用了模拟记录器


我个人使用EasyMock(及其“classextension”扩展)来模拟具体的类,但是还有其他模拟框架。阅读有关EasyMock和mocking的一般信息。

如果您试图测试在特定条件下引发的CustomException,那么您应该测试引发异常的代码,而不是捕获异常的代码。在您的示例中,我猜您未定义的“fileLoader”就是您希望抛出异常的对象


如果您试图测试异常是否被捕获,并且事情是否继续平稳运行,那么您需要重新设计ClassToTest,以便可以注入潜在异常抛出类的模拟实现。该模拟实现总是抛出异常。然后,您可以在测试中运行ClassToTest并断言表明它正确处理了异常的任何条件。

我认为正确的方法是将记录器传递到类中,如果您使用的是Mockito之类的模拟框架,您可以使用以下工具验证记录器:


这里的关键是传递您的依赖项,这样您就可以验证与它们的交互。

我从EasyMock开始,但现在强烈喜欢Mockito,它基于EasyMock,但扩展到更大的覆盖范围和更易于使用。看看@John,你应该投票选出所有你觉得有用的答案。(包括您选择接受的。)
ClassToTest myInstance = new ClassToTest(myLogger);

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