LoginSignup
11
7

More than 5 years have passed since last update.

【問題解決】MyBatisのTestで「Failed to replace DataSource with an embedded database for tests. 」というエラー発生

Last updated at Posted at 2018-01-24

環境

  • mybatis-spring-boot-starter: 1.3.1
    • mybatis: 3.4.5
  • mybatis-spring-boot-starter-test: 1.3.1
  • postgresql jdbc : 42.1.4
  • Spring Boot 1.5.9
  • Java8
  • PostgreSQL 9.6

やりたいこと

MyBatisを使ってDBにアクセスしています。
今、HotelDao.javafindByIdメソッドのテストを実施したいです。

HotelDao.java
@Component
public class HotelDao {

    private final SqlSession sqlSession;

    public HotelDao(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }

    public Hotel findById(long id) {
        return this.sqlSession.selectOne("findHotelById", id);
    }

}
HotelMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo2.mybatis.mapper.HotelMapper">

    <select id="findHotelById" resultType="com.example.demo2.mybatis.domain.Hotel">
        select * from hotel where city = #{id}
    </select>
</mapper>

問題

以下のような、findByIdメソッドを確認するテストコードを作成しました。

HotelDao.java
@RunWith(SpringRunner.class)
@MybatisTest
@Import({HotelDao.class})
public class HotelDaoTest {

    @Autowired
    private HotelDao hotelDao;

    @Test
    public void test() {
        Hotel hotel = hotelDao.findById(1);
        System.out.println(hotel);
        //assert
    }

}

JUnitで実行したら、以下のエラーが発生しました。

console
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2018-01-24 00:24:03.507 ERROR 46308 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'com.example.demo2.mybatis.dao.HotelDao': 
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'sqlSessionTemplate' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: 
Unsatisfied dependency expressed through method 'sqlSessionTemplate' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'sqlSessionFactory' defined in class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]: 
Unsatisfied dependency expressed through method 'sqlSessionFactory' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'dataSource': Invocation of init method failed; nested exception is java.lang.IllegalStateException: 
Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoconfigureTestDatabase.
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
...

※読みやすくするため、適当な箇所に改行を入れました。

原因

エラーの最後の方に、「Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoconfigureTestDatabase.」と記述されています。

書いてある内容は、

  • DataSourceをテスト用の組み込みデータベースに置き換えられなかった。
  • 組み込みデータベースを使いたいなら、サポートされている組み込みデータベースをクラスパスに追加するか、@AutoconfigureTestDatabasereplace属性を調整。

です。

@MyBatisTestを付与すると、デフォルトでは組み込みデータベースを設定します。しかし今のプロジェクトでは、組み込みデータベース用の設定(pom.xmlに定義していない)を行っていないので、エラーが発生しているようです。

The @MybatisTest can be used if you want to test MyBatis components(Mapper interface and SqlSession). By default it will configure MyBatis(MyBatis-Spring) components(SqlSessionFactory and SqlSessionTemplate), configure MyBatis mapper interfaces and configure an in-memory embedded database.

http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-test-autoconfigure/ 引用

解決1(@AutoConfigureTestDatabaseを設定)

テスト時にPostgreSQLを使う場合の対応方法です。

@AutoConfigureTestDatabase(replace = Replace.NONE)を追加しました。

HotelDaoTest.java
@RunWith(SpringRunner.class)
@MybatisTest
@AutoConfigureTestDatabase(replace = Replace.NONE) //追加
@Import({HotelDao.class})
public class HotelDaoTest {

    @Autowired
    private HotelDao hotelDao;

    @Test
    public void test() {
        Hotel hotel = hotelDao.findById(1);
        System.out.println(hotel);
    }

}

以下のサイトを参考にしました。

@AutoconfigureTestDatabaseについて

@AutoconfigureTestDatabaseのパッケージ

Spring Boot 1.5.9では、@AutoconfigureTestDatabaseが2種類あります。

  • org.springframework.boot.test.autoconfigure.orm.jp
  • org.springframework.boot.test.autoconfigure.jdbc

*.orm.jpの方は非推奨なので、*.jdbcの方を使います。

解決2(テスト時は組み込みデータベースを利用)

HSQLDBを利用します。

pom.xml
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <scope>runtime</scope>
</dependency>

テストデータを作成するSQLをsrc/test/resource/直下に置きます。
そうすると、テスト実行前にこのSQLが実行されます。

src/test/resource/schema.sql
CREATE TABLE hotel
(
  city integer NOT NULL ,
  name character varying(256),
  address character varying(256),
  zip character varying(256),
  CONSTRAINT pkey PRIMARY KEY (city)
);

insert into hotel(city, name, address, zip) values (1, 'Conrad Treasury Place', 'William & George Streets', '4001')

補足

組み込みデータベースについて

アプリケーションに組み込まれたデータベース。事前にデータベースを用意する必要がなく、アプリケーションの起動時にデータベースが構築されます。

Springでのデータベースの初期化

schema.sqlだけでなく、data.sqlというファイル名でも、自動的に実行されます。

Spring Boot can automatically create the schema (DDL scripts) of your DataSource and initialize it (DML scripts): it loads SQL from the standard root classpath locations schema.sql and data.sql, respectively.

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html#howto-initialize-a-database-using-spring-jdbc 引用

参考にしたサイト

11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7