0

我按照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

但是,这似乎符合规范!现在一切都很好。

4

2 回答 2

2

拦截器是使用代理实现的。由于第二个方法是从对象实例中调用的,因此代理无法捕获该调用,因此无法拦截该调用。为此,您需要引用 bean 的 CDI 代理。

于 2014-06-16T20:41:13.270 回答
-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

不幸的是,@Transactional(readOnly = true) 不起作用 - 不知道为什么。而且,与 Spring 等价物不同,它不会回滚事务,或在同一事务中运行 @Before/@After。

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

于 2015-06-05T10:30:47.473 回答