2014年3月20日木曜日

Spring DbUnit 設定

サービスのテスト作成


  • テストデータは Excel で用意、サービス毎にディレクトリを分けて管理。
  • トランザクションにより、テスト後には Rollback してデータを元に戻す。

pom.xml に追加。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${org.springframework-version}</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.10-FINAL</version>
</dependency>
<dependency>
    <groupId>org.dbunit</groupId>
    <artifactId>dbunit</artifactId>
    <version>2.4.9</version>
</dependency>

Eclipse で SampleService.java を開き、Ctrl + 9 でテスティングペアを作成する。
src/test/java/jp/s6131/sample/service/SampleServiceTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration
@Transactional
@ContextConfiguration(locations = {"
classpath:**/testApplicationContext.xml"})
public class SampleServiceTest extends DataSourceBasedDBTestCase{
    private final String RESOURCE_DIR = "src/test/resources/SampleServiceTest/";
    @Autowired
    private TransactionAwareDataSourceProxy dataSourceTest;
    @Autowired
    SampleService sampleService;
    @Before
    public void setUp() throws Exception{
        super.setUp();
    }
    @Test
    public void testSelectByCode() throws Exception{
        List<Sample> sampleList = sampleService.selectByCode("cd1");
        ITable it = new XlsDataSet(new File(RESOURCE_DIR + "testSelectByCode.xls")).getTable("sample");
        if (it == null) {
            fail("test data table not found.");
        }
        assertEquals(it.getRowCount(), sampleList.size());
        for (int i = 0; i < sampleList.size(); i++) {
            assertEquals(it.getValue(i, "id"), sampleList.get(i).getId().toString());
            assertEquals(it.getValue(i, "code"), sampleList.get(i).getCode());
            assertEquals(it.getValue(i, "name"), sampleList.get(i).getName());
        }
    }
    @Test
    public void testInsertList() throws Exception{
        ITable insertTable = new XlsDataSet(new File(RESOURCE_DIR + "testInsertList.xls")).getTable("sample");
        if (insertTable == null) {
            fail("test data table not found.");
        }
        List<Sample> sampleList = new ArrayList<Sample>();
        for (int i = 0; i < insertTable.getRowCount(); i++) {
            Sample sample = new Sample();
            sample.setId(new Long((String)insertTable.getValue(i,  "id")));
            sample.setCode((String)insertTable.getValue(i,  "code"));
            sample.setName((String)insertTable.getValue(i,  "name"));
            sampleList.add(sample);
        }
        int cnt = sampleService.insertList(sampleList);
        assertEquals(cnt, insertTable.getRowCount());
        ITable filteredCompareTable = getConnection().createQueryTable("SAMPLE_ORDER", "SELECT code, name FROM sample ORDER BY id");
        ITable resultTable = new XlsDataSet(new File(RESOURCE_DIR + "testInsertListResult.xls")).getTable("sample");
        ITable filteredResultTable = DefaultColumnFilter.excludedColumnsTable(resultTable, new String[]{"id"});
        assertEquals(filteredCompareTable.getRowCount(), filteredResultTable.getRowCount());
        Assertion.assertEquals(filteredCompareTable, filteredResultTable);
    }
    @Override
    protected void setUpDatabaseConfig(DatabaseConfig config) {
        config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory());
    }
    @Override
    protected DataSource getDataSource() {
        return dataSourceTest;
    }
    @Override
    protected IDataSet getDataSet() throws Exception {
        return new XlsDataSet(new File(RESOURCE_DIR + "import.xls"));
    }
}

テスト用設定ファイル

  • src/main/webapp/WEB-INF/spring/root-context.xml を複写して作成。
  • データソースは TransactionAwareDataSourceProxy に変更する。
src/test/resources/testApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jee="http://www.springframework.org/schema/jee"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/jee
    http://www.springframework.org/schema/jee/spring-jee.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- Root Context: defines shared resources visible to all other web components -->
    <context:component-scan base-package="jp.s6131.sample.service"/>
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>com.mysql.jdbc.Driver</value>
        </property>
        <property name="url">
            <value>jdbc:mysql://localhost/sample</value>
        </property>
        <property name="username">
            <value>s6131</value>
        </property>
        <property name="password">
            <value>パスワード</value>
        </property>
    </bean>
    <bean id="dataSourceTest"
        class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
        <constructor-arg ref="dataSource"/>
    </bean>
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource">
            <ref local="dataSourceTest" />
        </property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSourceTest" />
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="jp.s6131.sample.mapper" />
    </bean>
</beans>

初期データ Excel

src/test/resources/SampleServiceTest/import.xls
シート sample
id code name
1 cd1 名前1
2 cd1 名前2
3 cd1 名前3
4 cd2 名前4
5 cd2 名前5
6 cd3 名前6
7 cd4 名前7
8 cd4 名前8
9 cd4 名前9

testSelectByCode 検索結果 Excel

src/test/resources/SampleServiceTest/testSelectByCode.xls
シート sample
id code name
1 cd1 名前1
2 cd1 名前2
3 cd1 名前3

testInsertList 挿入データ Excel

src/test/resources/SampleServiceTest/testInsertList.xls
シート sample
id code name
10 cd5 名前10
11 cd5 名前11
12 cd5 名前12
13 cd5 名前13

testInsertList 挿入結果 Excel

src/test/resources/SampleServiceTest/testInsertListResult.xls
シート sample
id code name
1 cd1 名前1
2 cd1 名前2
3 cd1 名前3
4 cd2 名前4
5 cd2 名前5
6 cd3 名前6
7 cd4 名前7
8 cd4 名前8
9 cd4 名前9
10 cd5 名前10
11 cd5 名前11
12 cd5 名前12
13 cd5 名前13

テストの実行

SampleServiceTest.java を右クリック、「デバッグ」「JUnit テスト」を選択。
JUnitビューでテスト結果を確認。