読者です 読者をやめる 読者になる 読者になる

CDI-UnitとMyBatis-CDIを組み合わせる

CDI-UnitとMyBatis-CDIを組み合わせてハマった点を記載します。

サマリ

テストクラスに以下のアノテーションを指定する必要がありました。

(前略)
import org.mybatis.cdi.Extension;
import org.mybatis.cdi.SqlSessionManagerRegistry;
import 自分のパッケージ.SqlSessionFactoryProducer;
(中略)
@RunWith(CdiRunner.class)
@AdditionalClasses(value={Extension.class,SqlSessionFactoryProducer.class,SqlSessionManagerRegistry.class}) //コレ!
public class HogeTest extends TestCase {
(後略)

状況

素のJavaプロジェクトに以下のdepedenciesを突っ込んで、CDIを使ったコードをCDI-Unitでテストしました。

(前略)
<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
</dependency>
<dependency>
    <groupId>org.jglue.cdi-unit</groupId>
    <artifactId>cdi-unit</artifactId>
    <version>3.1.3</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.1</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-cdi</artifactId>
    <version>1.0.0-beta3</version>
</dependency>
(後略)

せつめい

CDI-Unitは、CDIコンテナを内蔵したJUnitのランナーで、実装としてWeldを使用します。

(参考:CDI-Unit will automatically use the version of Weld that was available when it was released.

また(そりゃランナーの目的からして明らかですが)JavaEE6までのように、beans.xmlを配置しなくてもCDIコンテナ(つまりWeld)は有効になりました(というか、beans.xml はあってもなくても変わらないっぽかったです)。

しかし、MyBatis-CDIで利用されている以下の3つのクラスは自動では読み込まれないため、上記のアノテーションCDI-Unitに読み込ませる必要がありました。

  • Extension
    • MyBatis-CDIのExtensionです。CDI Beanではないですが、CDIコンテナから呼び出される種類のもの。MyBatis-CDIのセットアップをする感じのものですね。
  • SqlSessionManagerRegistry
    • MyBatis-CDIで提供されるCDI Bean。
  • SqlSessionFactoryProducer
    • MyBatis-CDIを使うために自分で実装する必要があるProducerさん。

他のCDI Bean(テスト対象のCDI Beanとか)はちゃんと認識されて、テストが通ります。

上記3つは環境設定的なアレなので、テストクラスから明示的にたどれないという共通点があるので、

もしかしたらCDI-Unitは、テストクラスで利用しているCDI Beanだけを読み込んでいるのかもデスネ。


なに? CDIっていうかJavaEEならそもそもMyBatisじゃないだろって? JPAはこう……その、分かって!