I have a test that expects a particular exception, for example:
@Test(expected=MyException.class)
public void testMyMethod(){
myMethod();
}
The myMethod()
method actually throws a subclass of MyException
, lets call it MySubclassException
.
Is there anyway to define my test using the @Test
annotation to accept subclasses of MyException
as well as the class itself?
I know that I could simply write the test checking logic myself without using expected
by catching the exception and setting a flag, but I was wondering whether or not JUnit already supported matching exception subclasses.
This is already handled for you by the framework
Let's take a small example (very bad code): import static org.junit.Assert.*;
import org.junit.Test;
public class TestExpect {
@Test(expected=MyException.class)
public void test() throws MyException {
new Foo().foo();
}
}
With 2 exception classes MyException and MyExtendedException inheriting from the previous one and a simple Foo class like this one:
public class Foo {
public void foo() throws MyException{
throw new MyExtendedException();
}
}
Launching the test using the Eclipse runner prints a green bar because the test raises one instance of Myexception (is a relationship in POO)
If you prefer to read source code this is an exxcerpt from the Junit source code (ExpectException.java):
@Override
public void evaluate() throws Exception {
boolean complete = false;
try {
fNext.evaluate();
complete = true;
} catch (AssumptionViolatedException e) {
throw e;
} catch (Throwable e) {
if (!fExpected.isAssignableFrom(e.getClass())) {
String message= "Unexpected exception, expected<"
+ fExpected.getName() + "> but was<"
+ e.getClass().getName() + ">";
throw new Exception(message, e);
}
}
if (complete)
throw new AssertionError("Expected exception: "
+ fExpected.getName());
}
The test will pass if MyException
or MySubclassException
is thrown by myMethod()
. I tested the concept with this code:
public class ExceptionTest {
private static class ExceptionA extends Exception {
}
private static class ExceptionB extends ExceptionA {
}
@Test(expected=ExceptionA.class)
public void test() throws Exception {
throw new ExceptionB();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With