当前位置: 首页 > 知识库问答 >
问题:

CDI:当从JUnit测试调用拦截器时,不会调用拦截器

袁飞鹏
2023-03-14

我根据JBoss文档创建了一个拦截器。

为了测试拦截器,我把:

@Interceptor
@Transactional
public class TransactionalInterceptor {
  @AroundInvoke
  public Object intercept(InvocationContext ctx) throws Exception {
    System.out.println("intercept!");
    return ctx.proceed();
  }
}

现在,我想使用WeldJUnit4Runner类在单元测试中测试这个拦截器。

@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

不过,这似乎符合规范!现在一切都好了。

共有2个答案

彭坚壁
2023-03-14

可以使用DeltaSpike在正确初始化的CDIBean上运行测试,尽管它的文档和错误消息在不完全正确的情况下没有太大帮助。下面是让@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。属性

不幸的是,@Transactional(只读=true)不起作用——不知道为什么。而且,与Spring等价物不同,它不会回滚事务,也不会在同一事务中运行“之前/@之后”。

但是对于另一个拦截器,你只需要围绕测试方法本身就可以了。

能文华
2023-03-14

拦截器是使用代理实现的。因为第二个方法是从对象实例中调用的,所以调用不能被代理捕获,所以不能被拦截。要这样做,您需要引用bean的CDI代理。

 类似资料:
  • 问题内容: 我正在使用Java EE 6和Jboss AS7.1,并尝试使用拦截器绑定(来自jboss网站的示例)。 我有一个InterceptorBinding注解: 拦截器: 还有一个豆: 但是拦截器没有被称为。。。 在编写此代码时将调用拦截器: 谢谢你的帮助。 问题答案: 您是否按照参考示例中的说明启用了拦截器? 缺省情况下,bean档案没有通过拦截器绑定绑定的已启用拦截器。必须通过将侦听器

  • 问题内容: 我创建了一个RestEASY拦截器,以允许我在Web服务调用完成后在HTTP响应上设置标头值。我的代码看起来像这样… 但是,当我调用服务时,永远不会调用拦截器。我看到webservice调用成功完成,但是拦截器中的任何代码都没有执行过。除了注册拦截器,我还需要做些其他事情吗?是否必须在其他任何地方声明?是否需要包含任何特殊的web.xml参数? 问题答案: 您必须在web.xml的re

  • 我试图在我的应用程序中配置拦截器,但我无法使其工作。 在我的应用程序配置类中,我以以下方式进行了配置: 拦截器: 有人知道为什么没有被调用吗?

  • 问题内容: 我有这个代码 有什么方法可以在没有子类化或修改类且没有工厂的情况下拦截呼叫? 编辑:抱歉忘了提到这是在Android平台上。 问题答案: 您是否考虑过面向方面的编程,甚至还考虑过AspectJ?有关AspectJ / Android的信息,请参见此处和此处。

  • 问题内容: 我试图拦截所有AJAX调用,以检查AJAX响应是否包含我从PHP脚本作为JSON发送的特定错误代码(代码:ACCESS_DENIED,SYSTEM_ERROR,NOT_FOUND)。 我知道一个人可以做这样的事情: 但是-仅在“ ajaxSuccess”事件起泡到.log div时才起作用吗?我对么?通过将“ ajaxSuccess”事件绑定到文档可以实现我想要的东西吗? 我可以在jQ

  • 扩展说明 服务提供方和服务消费方调用过程拦截,Dubbo 本身的大多功能均基于此扩展点实现,每次远程方法执行,该拦截都会被执行,请注意对性能的影响。 约定: 用户自定义 filter 默认在内置 filter 之后。 特殊值 default,表示缺省扩展点插入的位置。比如:filter="xxx,default,yyy",表示 xxx 在缺省 filter 之前,yyy 在缺省 filter 之后