【问题解决】在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