Вам нужно расширить TestRule, в частности apply ().Для примера взгляните на org.junit.rules.ExternalResource & org.junit.rules.TevenFolder.
ExternalResource выглядит следующим образом:
public abstract class ExternalResource implements TestRule {
public Statement apply(Statement base, Description description) {
return statement(base);
}
private Statement statement(final Statement base) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
before();
try {
base.evaluate();
} finally {
after();
}
}
};
}
/**
* Override to set up your specific external resource.
* @throws if setup fails (which will disable {@code after}
*/
protected void before() throws Throwable {
// do nothing
}
/**
* Override to tear down your specific external resource.
*/
protected void after() {
// do nothing
}
}
TemporaryFolder затем расширяет это и реализуетbefore () и after ().
public class TemporaryFolder extends ExternalResource {
private File folder;
@Override
protected void before() throws Throwable {
// create the folder
}
@Override
protected void after() {
// delete the folder
}
Таким образом, before вызывается перед testMethod, а after вызывается в finally, но вы можете перехватывать и регистрировать любые исключения, например:
private Statement statement(final Statement base) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
before();
try {
base.evaluate();
} catch (Exception e) {
log.error("caught Exception", e);
} finally {
after();
}
}
};
}
РЕДАКТИРОВАТЬ: работает следующее:
public class SoTest {
public class ExceptionLoggingRule implements TestRule {
public Statement apply(Statement base, Description description) {
return statement(base);
}
private Statement statement(final Statement base) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (Exception e) {
System.out.println("caught an exception");
e.printStackTrace(System.out);
throw e;
}
}
};
}
}
@Rule public ExceptionLoggingRule exceptionLoggingRule = new ExceptionLoggingRule();
@Rule public ExpectedException expectedException = ExpectedException.none();
@Test
public void testMe() throws Exception {
expectedException.expect(IOException.class);
throw new IOException("here we are");
}
}
Тест проходит, и вы получаете следующий вывод:
caught an exception
java.io.IOException: here we are
at uk.co.farwell.junit.SoTest.testMe(SoTest.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
...
Порядок применения правил - ExpectedException, который вызываетExceptionLoggingRule, который вызывает метод testMe.ExceptionLoggingRule перехватывает исключение, регистрирует его и перебрасывает, а затем обрабатывает ExpectedException.
Если вы хотите регистрировать только непредвиденные исключения, вы просто переключаете порядок объявления правил:
@Rule public ExpectedException expectedException = ExpectedException.none();
@Rule public ExceptionLoggingRule exceptionLoggingRule = new ExceptionLoggingRule();
Таким образом, Ожидаемое исключение применяется первым (то есть вложенным в exceptionLoggingRule) и только сбрасывает исключения, которые не ожидаются.Кроме того, если какое-то исключение было ожидаемым и ни одного не произошло, ожидается, что ExException выдаст ошибку AssertionError, которая также будет зарегистрирована.
Этот порядок оценки не гарантирован, но он вряд ли изменится, если вы не играете с очень разными JVM или не наследуете между классами Test.
Если порядок оценки важен,тогда вы всегда можете передать одно правило другому для оценки.
РЕДАКТИРОВАТЬ: С недавно выпущенным Junit 4.10 вы можете использовать @RuleChain для правильной цепочки правил:
public static class UseRuleChain {
@Rule
public TestRule chain= RuleChain
.outerRule(new LoggingRule("outer rule")
.around(new LoggingRule("middle rule")
.around(new LoggingRule("inner rule");
@Test
public void example() {
assertTrue(true);
}
}
записывает журнал
starting outer rule
starting middle rule
starting inner rule
finished inner rule
finished middle rule
finished outer rule