Spring+JUnit+DbUnitではまる。。。

久しぶりにDbUnitを使おうとおもったらはまりまくった。

環境はeclipse3.4.1上のプロジェクト(古いけどこのときのシステムはこれで統一してたので。。。)
Springは2.5.6

まずアノテーション@RunWith(SpringJUnit4ClassRunner.class)を追加すると、

型 org.junit.internal.runners.JUnit4ClassRunner を解決できません。 必要な .class ファイルから間接的に参照されています

のエラーメッセージ。。。

Springにはいっていたjunit-4.4.jarをクラスパスに追加して解決。

初期データをDataSetからCLEAN_INSERTを行っても、テスト実行時は別のトランザクションになってしまいテストができなかった。。。

データソースをとってくるところをorg.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
に変更。
元のDBCPのところはidをdbcpDataSourceにして以下を追加

  <bean id="dataSource"
    class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
    <constructor-arg ref="dbcpDataSource" />
  </bean>

これで解決。

  • 3つ目のはまり実行時例外

さてテストを実行しようとしたら

java.lang.SecurityException: class "org.junit.internal.runners.JUnit4ClassRunner"'s signer information does not match signer information of other classes in the same package

はぅ。。。
ライブラリが競合してたみたい。。。
junit-4.4.jarの順序を変更したら動くようになった。



さて、テストがんばりましょか。

とりあえず、動いたソースをアップ
内容は初期データを取り込んだテーブルをSELECTで取り出し
結果をExcelで比較する。
BeanのリストをIDataSetにするのは、
http://sourceforge.jp/projects/dbunitng/
を使わせていただきました。

import java.io.BufferedInputStream;
import java.net.URL;
import java.util.List;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.apache.log4j.xml.DOMConfigurator;
import org.dbunit.Assertion;
import org.dbunit.DataSourceDatabaseTester;
import org.dbunit.IDatabaseTester;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.excel.XlsDataSet;
import org.dbunitng.dataset.BeanListConverter;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@Transactional
@TransactionConfiguration(defaultRollback = true)
@ContextConfiguration(locations = "/resources/spring/batchApplicationContext.xml")
public class DbUnitTest {
    private static final String LOG4J_CONFIG_FILE = "src/main/resources/log4j/log4j.xml";
    private IDatabaseTester tester;

    @Autowired
    private DbUnitDao dbUnitDao;
    @Resource
    private DataSource dataSource;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        DOMConfigurator.configure(LOG4J_CONFIG_FILE);
    }

    @Before
    public void setUp() throws Exception {
        tester = new DataSourceDatabaseTester(dataSource);
        tester.setDataSet(getDataSet());
        tester.onSetup();
    }

    @After
    public void after() throws Exception {
        tester.onTearDown();
    }

    protected IDataSet getDataSet() throws Exception {
        URL url = DbUnitTest.class.getResource("import-data.xls");
        BufferedInputStream is = new BufferedInputStream(url.openStream());
        XlsDataSet dataset = new XlsDataSet(is);

        return dataset;
    }

    @Test
    public void hogehoge() throws Exception {
        List<DbUnitBean> list = dbUnitDao.queryAll();
        BeanListConverter converter = new BeanListConverter(list);
        IDataSet dataSet = converter.convert();

        URL url = DbUnitTest.class.getResource("expected-data.xls");
        BufferedInputStream is = new BufferedInputStream(url.openStream());
        XlsDataSet expected = new XlsDataSet(is);

        Assertion.assertEquals(expected, dataSet);

    }
}