Expect an exception or one of its subclasses in Junit Test with @Test annotation

I have a test that expects a specific exception, for example:

@Test(expected=MyException.class) public void testMyMethod(){ myMethod(); } 

The myMethod() method actually creates a subclass of MyException , allowing you to call it MySubclassException .

Is there a way to define my test using the @Test annotation to accept subclasses of MyException , as well as the class itself?

I know that I could just write the test test logic myself, without using expected , catching the exception and setting the flag, but I was wondering if JUnit supports the corresponding exception subclasses.

+8
java unit-testing junit junit4
source share
3 answers

This has already been processed for you by the framework.

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 two exception classes MyException and MyExtendedException inheriting from the previous one and a simple Foo class like this:

 public class Foo { public void foo() throws MyException{ throw new MyExtendedException(); } } 

Running a test using an Eclipse runner prints a green bar because the test raises a single instance of Myexception (this is the ratio in POO)

If you prefer to read the source code, this is 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()); } 
+3
source share

The test passes if MyException or MySubclassException 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(); } } 
+3
source share

BDD Style Solution with Catch Elimination

 @Test public void testMyMethod() { when(foo).myMethod(); then(caughtException()).isInstanceOf(MyException.class); } 

Dependencies

 com.googlecode.catch-exception:catch-exception:1.2.0 
0
source share

All Articles