【问题解决】在MyBatis的测试中出现了“无法替换测试用的嵌入式数据库的数据源”这个错误

环境

    • 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访问数据库。
现在,我想要执行HotelDao.java中findById方法的测试。

@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);
    }

}
<?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方法。

@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进行执行时,发生了以下错误。

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]
...

※為了易於閱讀,在適當位置加入換行。

导致这种情况的原因是什么?

在错误的最后部分中写着:“在测试中无法使用嵌入式数据库替换数据源。如果您想要使用嵌入式数据库,请将一个支持的数据库放置在类路径上,或调整`@AutoconfigureTestDatabaser`的替换属性。”

书面内容表明

    • DataSourceをテスト用の組み込みデータベースに置き換えられなかった。

 

    組み込みデータベースを使いたいなら、サポートされている組み込みデータベースをクラスパスに追加するか、@AutoconfigureTestDatabaseのreplace属性を調整。

是的。

添加@MyBatisTest注解时,默认配置嵌入式数据库。但是在当前项目中,没有进行嵌入式数据库的配置(未在pom.xml文件中定义),因此出现了错误。

如果您想要测试MyBatis组件(Mapper接口和SqlSession),可以使用@MybatisTest。默认情况下,它会配置MyBatis(MyBatis-Spring)组件(SqlSessionFactory和SqlSessionTemplate),配置MyBatis mapper接口,并配置一个内存中的嵌入式数据库。

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

解决1(设置@AutoConfigureTestDatabase)

这是在测试时使用PostgreSQL的应对方法。

我已经添加了@AutoConfigureTestDatabase(replace = Replace.NONE)。

@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);
    }

}

我参考了下面的网站。

    • Using a real database – MyBatis

 

    • Spring-boot-starter-test cannot run database integration test

Sprint Boot 1.4 @DataJpaTest – Error creating bean with name ‘dataSource’

关于@AutoconfigureTestDatabase

    Annotation Type AutoConfigureTestDatabase

@AutoconfigureTestDatabase 包的目录

在Spring Boot 1.5.9中,存在两种类型的@AutoconfigureTestDatabase。

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

 

    org.springframework.boot.test.autoconfigure.jdbc

由于.orm.jp已被弃用,请使用.jdbc。

針對2進行解決(在測試時使用內建數據庫)。

使用HSQLDB。

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

将创建测试数据的SQL放置在src/test/resource/的根目录下。
这样,在执行测试之前,该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')

填补

嵌入式数据库相关内容

在应用程序中集成的数据库。无需预先准备数据库,在应用程序启动时会构建数据库。

    埋込RDBの利用(Derby,HSQLDB,H2ライブラリの性能比較)

在Spring中初始化数据库。

不仅仅是 schema.sql,也会自动执行名为 data.sql 的文件。

Spring Boot可以自动创建您的DataSource的模式(DDL脚本)并对其进行初始化(DML脚本):它分别从标准的根类路径位置schema.sql和data.sql加载SQL。

请使用Spring JDBC方法来初始化数据库,请参考文档:https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html#howto-initialize-a-database-using-spring-jdbc。

参考网站

    • Spring-boot-starter-test cannot run database integration test

Sprint Boot 1.4 @DataJpaTest – Error creating bean with name ‘dataSource’

@JdbcTest detect class annotated @SpringBootApplication
mybatis-spring-boot-test-autoconfigure

bannerAds