Si está utilizando la versión más reciente de JUnit se puede ampliar el corredor de prueba por defecto para manejar esto para usted (sin tener que ajustar cada uno de sus métodos en un bloque try/catch)
ExtendedTestRunner.java - nuevo corredor de prueba:
public class ExtendedTestRunner extends BlockJUnit4ClassRunner
{
public ExtendedTestRunner(Class<?> clazz)
throws InitializationError
{
super(clazz);
}
@Override
protected Statement possiblyExpectingExceptions(FrameworkMethod method,
Object test,
Statement next)
{
ExtendedTest annotation = method.getAnnotation(ExtendedTest.class);
return expectsCauseException(annotation) ?
new ExpectCauseException(next, getExpectedCauseException(annotation)) :
super.possiblyExpectingExceptions(method, test, next);
}
@Override
protected List<FrameworkMethod> computeTestMethods()
{
Set<FrameworkMethod> testMethods = new HashSet<FrameworkMethod>(super.computeTestMethods());
testMethods.addAll(getTestClass().getAnnotatedMethods(ExtendedTest.class));
return testMethods;
}
@Override
protected void validateTestMethods(List<Throwable> errors)
{
super.validateTestMethods(errors);
validatePublicVoidNoArgMethods(ExtendedTest.class, false, errors);
}
private Class<? extends Throwable> getExpectedCauseException(ExtendedTest annotation)
{
if (annotation == null || annotation.expectedCause() == ExtendedTest.None.class)
return null;
else
return annotation.expectedCause();
}
private boolean expectsCauseException(ExtendedTest annotation) {
return getExpectedCauseException(annotation) != null;
}
}
ExtendedTest.java - anotación para marcar con los métodos de ensayo:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ExtendedTest
{
/**
* Default empty exception
*/
static class None extends Throwable {
private static final long serialVersionUID= 1L;
private None() {
}
}
Class<? extends Throwable> expectedCause() default None.class;
}
ExpectCauseException.java - nueva Declaración JUnit:
public class ExpectCauseException extends Statement
{
private Statement fNext;
private final Class<? extends Throwable> fExpected;
public ExpectCauseException(Statement next, Class<? extends Throwable> expected)
{
fNext= next;
fExpected= expected;
}
@Override
public void evaluate() throws Exception
{
boolean complete = false;
try {
fNext.evaluate();
complete = true;
} catch (Throwable e) {
if (e.getCause() == null || !fExpected.isAssignableFrom(e.getCause().getClass()))
{
String message = "Unexpected exception cause, expected<"
+ fExpected.getName() + "> but was<"
+ (e.getCause() == null ? "none" : e.getCause().getClass().getName()) + ">";
throw new Exception(message, e);
}
}
if (complete)
throw new AssertionError("Expected exception cause: "
+ fExpected.getName());
}
}
Uso:
@RunWith(ExtendedTestRunner.class)
public class MyTests
{
@ExtendedTest(expectedCause = MyException.class)
public void someMethod()
{
throw new RuntimeException(new MyException());
}
}
poco importante nota lateral: se "espera = ...", no "esperar = ..." – hoijui
No puedo creer JUnit 5 al parecer no ha aumentado su sintaxis de anotación para incluir esta. –