我在JBoss documentation之后创建了一个拦截器。
为了测试拦截器,我把:
@Interceptor
@Transactional
public class TransactionalInterceptor {
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
System.out.println("intercept!");
return ctx.proceed();
}
}
现在我想使用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");
}
}
现在预期的输出当然是
intercept!
testMethod
intercept!
anotherMethod
但相反,输出是
intercept!
testMethod
anotherMethod
主要的问题是,如果我在我的测试中注入一个bean也是如此:我调用的bean的第一个方法被拦截,但是如果这个方法调用另一个方法,则不会调用拦截器。
任何想法都非常感谢!
我只是按照@adrobisch的建议尝试修改我的代码,这有效:
@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");
}
}
输出是(正如预期的那样)
intercept!
testMethod
intercept!
anotherMethod
然而,以下不工作:
@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");
}
}
这里的输出是
testMethod
anotherMethod
然而,这似乎是根据规范!一切都很好。
答案 0 :(得分:2)
拦截器是使用代理实现的。由于第二个方法是从对象实例中调用的,因此代理无法捕获该调用,因此无法拦截该调用。您需要引用bean的CDI代理才能这样做。
答案 1 :(得分:-1)
可以使用DeltaSpike在正确初始化的CDI bean上运行测试,尽管它的文档和错误消息在它不完全正确时不是很有用。这是为了让@Transactional拦截器工作的方法:
@Transactional // the @Transactional from org.apache.deltaspike.jpa.api.transaction
@TestControl(startScopes = { TransactionScoped.class })
@RunWith(CdiTestRunner.class)
public MyTestClass { ... }
然后添加:
deltaspike.testcontrol.use_test_class_as_cdi_bean=true
到src / test / resources / META-INF / apache-deltaspike.properties
不幸的是,@ Transaction(readOnly = true)不起作用 - 不明白为什么。并且,与Spring等价物不同,它不会回滚事务,也不会在同一事务中运行@ Before / @ After。
但对于另一个拦截器,你只需要测试方法本身就可以了。