Question

I have question that similar to my previous question where I have the following class:

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

I would like to test whether ClassNotFoundException will be thrown when funcB() is called. Thus I have this test code:

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();
    }
}

But the test were failed due to following error:

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)

Any clue how could I test ClassNotFoundException in funcB()?

Was it helpful?

Solution

If you're testing a method invocation on an instance of type FileClass, don't mock the instance. Just create an actual instance and call the method.

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

Mocking is meant for things that you know ([would]) work but don't want to setup.

As @dzezzz states in the comments, a ClassNotFoundException (is that really the exception you want to test?) could be thrown in the FileClass constructor. If that is not something that should happen and that you want to test, you can set up the following test so that it is only expected from the method invocation

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

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

The test will pass only if a ClassNotFoundException is thrown after the ExpectedException#expect() call.

OTHER TIPS

If you test FileClass then don't mock it. You should mock the classes which are used by FileClass. If you don't want that the exception will come out from test method. There is a solution:

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

In this solution you catch the exception if it is thrown but your test fails when it isn't.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top