Java Reference
In-Depth Information
@Override
public void
evaluate()
throws
Throwable {
for
(Interceptor interceptor:interceptors) {
interceptor.interceptBefore();
}
F
G
H
invoker.evaluate();
for
(Interceptor interceptor:interceptors) {
interceptor.interceptAfter();
}
}
I
J
public void
addInterceptor(Interceptor interceptor) {
interceptors.add(interceptor);
}
}
As we already discussed, after
JU
nit 4.5 every test is executed by a block of statements.
1
Here we create our
InterceptorStatement
by extending the
Statement
object
B
,
and we override the
evaluate
method
F
. Our statement holds a statement to invoke
C
and a list of
Interceptor
implementations
D
that were added to it
J
. In the con-
structor we initialize the
invoker
statement
E
that we're wrapping. The
evaluate
method
F
implements the entire logic of the statement; it iterates over all the inter-
ceptors and invokes their
interceptBefore
method
G
. Next we invoke the
evaluate
method of the wrapped statement object
H
and again iterate over all the interceptors,
this time to invoke the
interceptAfter
method
I
.
Now that we've prepared the
InterceptorStatement
object, it's time to move
on and implement the real heart of the custom
JU
nit runner that we're making. We
do this by extending the
BlockJUnit4ClassRunner
class, as shown in listing B.3,
which was added in version 4.5 of the
JU
nit framework to help people create cus-
tom runners.
Listing B.3
Custom JUnit runner—
InterceptorRunner
[...]
import
org.junit.runners.BlockJUnit4ClassRunner;
B
public class
InterceptorRunner
extends
BlockJUnit4ClassRunner {
C
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.TYPE )
public
@interface InterceptorClasses {
D
public
Class<?>[] value();
}
public
InterceptorRunner(Class<?> clazz)
throws
InitializationError {
super
( clazz );
}
E
1
For more on this topic you can read an article by Kent Beck here:
http://threeriversinstitute.org/
TwoMoreImplementationPatterns.htm.