Java Reference
In-Depth Information
F
@Override
public
Statement methodInvoker(FrameworkMethod method, Object test) {
InterceptorStatement statement =
new
InterceptorStatement(
super
.methodInvoker( method, test ));
InterceptorClasses annotation =
test
.getClass().getAnnotation(
InterceptorClasses.
class
);
Class<?>[] klasez = annotation.value();
try
{
for
(Class<?> klaz : klasez) {
statement.addInterceptor((Interceptor) klaz.newInstance());
}
}
catch
( IllegalAccessException ilex ) {
ilex.printStackTrace();
}
catch
( InstantiationException e ) {
e.printStackTrace();
}
return
statement;
}
}
G
H
I
J
1)
As we just said, in order to implement a custom
JU
nit runner we need to extend the
BlockJUnit4ClassRunner
B
. In our custom runner we also declare an annotation
called
@InterceptorClasses
at
C
, which we use to hold the implementations of the
Interceptor
interface that we want to plug into our execution. Our
@Interceptor-
Classes
annotation defines a
value()
method, to return the classes that it holds at
D
. In
E
we define the constructor that we must have, and in
F
we override the
methodInvokerStatement
method. We start the method by creating an instance of our
InterceptorStatement
at
G
.
Notice that the
InterceptorStatement
we wrote in listing B.2 accepts a statement
to wrap around. We create this statement by calling the
super.methodInvoker
method
with parameters: our test method and the test class. This creates a
Statement
one level
closer to the core of the statement block. And because the core of the statement block
is the test itself, we wrap the test in our custom statement.
At
H
we obtain the
@InterceptorClasses
annotation, which must be defined
for the test class. Then, in
I
, we get all the classes that the annotation holds, iter-
ate over the collection of classes, and add them to the
InterceptorStatement
object
at
J
. The last step is to return our ready-made
InterceptorStatement
object .
Our custom
JU
nit runner is finished! But in order to use it we need some sample
implementations of the
Interceptor
interface. Here comes the real question: “What
kind of events do we want to plug into the execution of the tests?”
One of the simplest implementations that could possibly come to mind is a logging
implementation; we log a message before and after execution of every test. Listing B.4
contains the code for this interceptor.
1)