wancoro blog

学んだことをアウトプットしていきたいと思います

【JUnit5】DBUnitを使ってDaoのテストを実装する

難しくて1週間くらいかかりました・・・。

実装環境

テストしたいコード

@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<UserModel> getUser(Integer id) {
        List<UserModel> list = jdbcTemplate.query("SELECT * FROM users WHERE id=?", new Object[]{id},
                new RowMapper<UserModel>() {
                    public UserModel mapRow(ResultSet resultSet, int rowNum) throws SQLException {
                        UserModel user = new UserModel();
                        user.setId(resultSet.getInt("id"));
                        user.setName(resultSet.getString("name"));
                        return user;
                    }
                });
        return list;
    }
}

idでSELECTしたuserのリストを返却する簡単なもの

事前準備

テスト用のDBを用意しておく

database name user password
springmvc_test pgadmin pgadmin
column type
id integer
name varchar(16)

実装手順

ライブラリを追加

pom.xmlを編集する

<dependency>
  <groupId>org.dbunit</groupId>
  <artifactId>dbunit</artifactId>
  <version>2.6.0</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>com.github.springtestdbunit</groupId>
  <artifactId>spring-test-dbunit</artifactId>
  <version>1.3.0</version>
  <scope>test</scope>
</dependency>

テスト用コンテキストファイルを作成する

// src/main/webapp/WEB-INF/test-context.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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven/>

    <context:component-scan base-package="com.springMvcTutorial.controllers"/>
    <context:component-scan base-package="com.springMvcTutorial.dao" />
    <context:component-scan base-package="com.springMvcTutorial.models" />
    <context:component-scan base-package="com.springMvcTutorial.services" />


    // テスト用のDBを設定する 
    <bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql://localhost:5432/springmvc_test" />
        <property name="username" value="pgadmin" />
        <property name="password" value="pgadmin" />
    </bean>

    <bean class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg ref="dataSource" />
    </bean>
</beans>

テスト用DBにインサートするxmlファイルを用意する

// src/test/resources/data/insert_test_user.xml

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <USERS
        ID="10"
        NAME="testUser"
    />
</dataset>

テストクラスを実装する

@SpringJUnitWebConfig(locations = { "file:src/main/webapp/WEB-INF/test-context.xml"} )
@TestExecutionListeners({
        ServletTestExecutionListener.class,
        DirtiesContextBeforeModesTestExecutionListener.class,
        DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class,
        TransactionDbUnitTestExecutionListener.class})
class UserDaoImplTest {

    @Autowired
    private WebApplicationContext webApplicationContext;
    private JdbcTemplate jdbcTemplate;

    @Inject
    private UserDaoImpl userDao;

    @Test
    @DatabaseSetup("/data/insert_test_user.xml")
    @DisplayName("getUser on userDaoImpl")
    void getUser() throws Exception {
        UserModel user = new UserModel();
        user.setId(10);
        user.setName("testUser");

        List<UserModel> users = Arrays.asList(user);

        List<UserModel> resultWithUser = userDao.getUser(10);
        List<UserModel> resultNoUser = userDao.getUser(1);

        assertEquals(resultWithUser.size(), 1);
        assertEquals(resultWithUser, users);
        assertEquals(resultNoUser.size(), 0);
    }
}

解説

  • テスト用のコンテキストファイルパスを指定する
@SpringJUnitWebConfig(locations = { "file:src/main/webapp/WEB-INF/test-context.xml"} )
  • JdbcTemplateをインジェクトする
@Autowired
private WebApplicationContext webApplicationContext;
private JdbcTemplate jdbcTemplate;
  • テスト対象のクラスをインジェクトする
@Inject
private UserDaoImpl userDao;
  • テスト用のsqlを読み込みする
    (デフォルトではCLEAN_INSERTでの実行となり、
    XMLファイルで参照しているテーブルのデータを削除してから新しくレコードが挿入される)
@DatabaseSetup("/data/insert_test_user.xml")

参考資料

springtestdbunit.github.io