I have created an interceptor following the JBoss documentation.
To test the interceptor, I put:
@Interceptor
@Transactional
public class TransactionalInterceptor {
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
System.out.println("intercept!");
return ctx.proceed();
}
}
Now I wanted to test this interceptor in a unit test, using the WeldJUnit4Runner class.
@RunWith(WeldJUnit4Runner.class)
public class MyTest {
@Test
@Transactional // the interceptor I created
public void testMethod() {
System.out.println("testMethod");
anotherMethod();
}
@Transactional
public void anotherMethod() {
System.out.println("anotherMethod");
}
}
Now the expected output would of course be
intercept!
testMethod
intercept!
anotherMethod
But instead, the output is
intercept!
testMethod
anotherMethod
The main problem is that this is also true if I inject a bean into my test: The first method of the bean that I call gets intercepted, but if this method calls another method, the interceptor is not invoked.
Any ideas at all are much appreciated!
I just tried to modify my code as suggested by @adrobisch, and this works:
@RunWith(WeldJUnit4Runner.class)
public class MyTest {
@Inject
private MyTest instance;
@Test
@Transactional // the interceptor I created
public void testMethod() {
System.out.println("testMethod");
instance.anotherMethod();
}
@Transactional
public void anotherMethod() {
System.out.println("anotherMethod");
}
}
The output is (as expected)
intercept!
testMethod
intercept!
anotherMethod
However, the following does not work:
@RunWith(WeldJUnit4Runner.class)
public class MyTest {
@Inject
private MyTest instance;
@Test
// @Transactional <- no interceptor here!
public void testMethod() {
System.out.println("testMethod");
instance.anotherMethod();
}
@Transactional
public void anotherMethod() {
System.out.println("anotherMethod");
}
}
The output here is
testMethod
anotherMethod
This seems to be according to spec, however! Everything is fine now.
Interceptors are implemented using proxies. Since the second method is called from within the object instance, the call can't be catched by the proxy and so it can't be intercepted. You would need a reference to the CDI proxy of your bean to do so.