簡體   English   中英

CDI:從JUnit測試調用時,不會調用Interceptor

[英]CDI: Interceptor is not invoked when called from a JUnit test

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

但是,這似乎符合規范! 現在一切都很好。

攔截器是使用代理實現的。 由於第二個方法是從對象實例內部調用的,因此代理無法捕獲該調用,因此也無法攔截該調用。 為此,您需要引用bean的CDI代理。

可以使用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。

但是對於另一個攔截器,您只需要圍繞測試方法本身就可以了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM