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

インターセプターは、プロキシーを使用して実装されます。2 番目のメソッドはオブジェクト インスタンス内から呼び出されるため、呼び出しはプロキシによってキャッチされず、傍受されません。そのためには、Bean の CDI プロキシへの参照が必要です。

于 2014-06-16T20:41:13.270 に答える
-1

適切に初期化された CDI Bean で DeltaSpike を使用してテストを実行することは可能ですが、正確に正しくない場合、ドキュメントとエラー メッセージはあまり役に立ちません。@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 に答える