【问题标题】:How could I test ClassNotFoundException is being thrown?我怎么能测试 ClassNotFoundException 被抛出?
【发布时间】:2014-01-08 06:15:38
【问题描述】:

我的问题类似于我的previous question,我有以下课程:

public class FileClass {
    public void funcB() throws ClassNotFoundException {
        throw new ClassNotFoundException();
    }
}

我想测试在调用funcB() 时是否会抛出ClassNotFoundException。因此我有这个测试代码:

public class TestFileClass {
    @Test(expected=ClassNotFoundException.class)
    public void testFuncB() throws ClassNotFoundException {
        FileClass fc = Mockito.spy(new FileClass());
        Mockito.doThrow(new ClassNotFoundException())
        .when(fc).funcB();
    }
}

但由于以下错误导致测试失败:

java.lang.AssertionError: Expected exception: java.lang.ClassNotFoundException
    at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:35)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

任何线索我如何在funcB() 中测试ClassNotFoundException

【问题讨论】:

    标签: java mockito classnotfoundexception powermock


    【解决方案1】:

    如果您在 FileClass 类型的实例上测试方法调用,请不要模拟该实例。只需创建一个实际实例并调用该方法即可。

    @Test(expected = ClassNotFoundException.class)
    public void testFuncB() throws ClassNotFoundException {
        FileClass fc = new FileClass();
        fc.funcB();
    }
    

    模拟适用于您知道([将])工作但不想设置的东西。

    正如@dzezzz 在 cmets 中所说,ClassNotFoundException(这真的是您要测试的异常吗?)可以在 FileClass 构造函数中抛出。如果这不是应该发生的事情并且您想要测试,您可以设置以下测试,以便仅在方法调用中预期它

    @Rule
    public ExpectedException exception = ExpectedException.none();
    
    @Test()
    public void testFuncB() throws ClassNotFoundException {
        FileClass fc = new FileClass();
        exception.expect(ClassNotFoundException.class);
        fc.funcB();
    }
    

    只有在ClassNotFoundException 被抛出ExpectedException#expect() 调用之后,测试才会通过。

    【讨论】:

    • 如果在 FileClass 构造函数中抛出此异常,则该测试将通过。最好在调用 funcB 之前使用 ExpectedException @Rule 并期望异常。
    • @dzezzz 好点。 ClassNotFoundExcepton 几乎可以在任何地方发生,但它确实有助于限制我们想要测试的范围。尽管 IMO,OP 确实不应该测试该异常。
    【解决方案2】:

    如果您测试 FileClass,请不要模拟它。您应该模拟 FileClass 使用的类。 如果您不希望异常来自测试方法。 有一个解决办法:

    @Test(expected = ClassNotFoundException.class)
    public void testFuncB(){
        try{
            FileClass fc = new FileClass();
            fc.funcB();
            fail();
        }catch(ClassNotFoundException ex){
        }
    }
    

    在此解决方案中,如果抛出异常,您将捕获该异常,但如果没有抛出,您的测试将失败。

    【讨论】:

    • 删除expected
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多