打算写单元测试时,应该是集成测试,想用h2这个内存数据库来代替mysql,目的是让测试变得方便。
- 首先是写了个demo,在网上找的,地址是
http://blog.youkuaiyun.com/mn960mn/article/details/54644908
。在src/test/java
目录下,对一个User对象进行增删改操作,使用h2作为数据库,数据源的配置是:
spring:
datasource:
url: jdbc:h2:mem:db_users;MODE=MYSQL;INIT=RUNSCRIPT FROM './src/test/resources/init_table.sql'
username: sa
password: 123
driverClassName: org.h2.Driver
- 这个测试是通过的,说明h2这样配置是有用的,可以从配置看出,连接数据源的时候初始化了数据库,然后可能就一直使用这个连接来测试;因为目前的项目用了flyway这个版本管理工具,所以它的sql语句不方便整合到一个sql文件中,所以就想使用flyway来初始化h2。
- 接着引入了flyway的依赖,通过去它的官网查到,它有几种方式的使用,有命令行的,还有api的,然后我就使用了api,这个比较熟悉一点;写好
/src/test/resource/db/migration/V1.0__init_table.sql
,调用api初始化:
@Before
public void setup(){
// Create the Flyway instance
Flyway flyway = new Flyway();
// Point it to the database
flyway.setDataSource("jdbc:h2:mem:db_users;DB_CLOSE_DELAY=-1", "sa", "123");
// Start the migration
flyway.migrate();
}
- 在设置数据源的时候,要加上
DB_CLOSE_DELAY=-1
这个参数,开始的时候就是因为没有这个参数,导致测试的时候一直找不到table,因为对h2还不熟悉,一直在找资料,但是没有用‘h2找不到table’
这个条件来搜,很久才找到问题,google上搜到https://stackoverflow.com/questions/5763747/h2-in-memory-database-table-not-found/5764011
;然后就是用户名密码也设置一下,用的时候设置一样就好了,如果不设置的话就会报错误的用户名密码什么的。 - 最后测试通过。看来还是需要多了解一下h2,还有查找资料的时候要用关键字去找,出什么问题概括一下这个问题,否则就浪费时间了。
- 在使用flyway时,设置flyway.locations有两种寻找sql文件的方式,一种是classpath前缀,指
resources
资源目录,另一种是filesystem前缀,指文件系统目录,当前指的是项目的根目录,和src
并列,如:filesystem:../../test/db/migrations
。 - 当启动单元测试的时候,我在
setUp()
方法里写了数据库迁移的代码:
@Before
public void setup(){
// Create the Flyway instance
Flyway flyway = new Flyway();
// Point it to the database
flyway.setDataSource("jdbc:h2:mem:db_dtdream_op;DB_CLOSE_DELAY=-1;MODE=MYSQL", "sa", "123");
flyway.setLocations("filesystem:../../other/db/migrations");
// Start the migration
flyway.migrate();
}
然后一直报错,Flyway Validate failed:migration checksum mismatch
,这是因为@SpringBootTest这个注解会启动整个应用的环境,flyway的自动配置也启动了,FlywayAutoConfiguration
配置了flyway的初始化器,然后默认的进行了数据迁移,所以我重复了这个动作,而且sql文件的来源也不一样,但版本号是从1.0开始的,导致报错。这还是在debug下打断点看源码才发现的,flyway.migrate()
调了两次。接着就是在配置文件里配flyway.enable=flase
不允许flyway的自动装配才解决。
看来对springboot的自动装配还是要去了解一下,究竟什么时候回启动自动装配,启动哪些自动配置等等。
上面的问题解决完后,启动单元测试,发现执行不了sql文件,有语法错误,找了好久也没有找到解决办法,不清楚h2的sql语句有什么要求,没办法,只能去现有的数据通过Navicat导出那张出错的表的建表语句,然后替换,执行就通过了。
但是历史的建表语句找不到了,很麻烦。