单元测试的重要性不必多说,大家都知道,在以前我做单元测试经常有一个很头疼的事情,已经写好的unit test经常会因为数据库中的某个数据被其他开发人员有心或无心删掉,导致unit test在之前还能通过,但是时间一长要重跑单元测试的时候就一堆不通过的。现在有了h2数据库,这个问题可以说可以完美解决。h2数据库是内存数据库,完美支持各大关系型数据库如:MySql、Oracle的语法,h2数据库简直就是为数据持久层单元测试而生的。
废话不多说,直接来看看SpringBoot 的2.0版本如何集成h2+liquibase进行单元测试吧。
首先maven依赖:
<!--liquibase 依赖-->
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.5.5</version>
</dependency>
<!--h2数据库 单元测试用 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
接下来看DAO层的简单demo:
public class Client implements Serializable {
private Long id;
private String name;
private String remark;
private Date createdAt;
private Date updatedAt;
//省略 getter setter方法
}
@Mapper
public interface ClientMapper {
public void insert(Client client);
public Client queryById(Long id);
}
resources下面创建db/changelogs/目录添加文件changelog-master.xml,该文件为liquibase的配置文件。
changelog-master.xml文件和changelog-init.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<include file="changelog-init.xml" relativeToChangelogFile="true" />
</databaseChangeLog>
changelog-init.xml 内容如下
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
<changeSet id="20190116" author="lai yao">
<createTable tableName="client">
<column name="id" type="BIGINT UNSIGNED" autoIncrement="true">
<constraints primaryKey="true" />
</column>
<column name="name" type="VARCHAR(20)">
<constraints nullable="false" />
</column>
<column name="remark" type="VARCHAR(100)">
<constraints nullable="true" />
</column>
<column name="created_at" type="TIMESTAMP(3)" defaultValueComputed="NOW(3)">
<constraints nullable="false" />
</column>
<column name="updated_at" type="TIMESTAMP(3)" defaultValueComputed="NOW(3) ON UPDATE NOW(3)">
<constraints nullable="true" />
</column>
</createTable>
</changeSet>
</databaseChangeLog>
最后单元测试:
public class TestApplicationContextInitializer implements ApplicationContextInitializer<GenericApplicationContext> {
@Override
public void initialize(GenericApplicationContext applicationContext) {
Properties props =new Properties();
//根据需求添加测试使用的配置
MutablePropertySources sources = applicationContext.getEnvironment().getPropertySources();
if(props != null && !props.isEmpty()){
Map<String,Object> map = new HashMap<>((Map)props);
sources.addLast(new MapPropertySource("defaultProperties",map));
}
}
}
//单元测试demo
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {App.class},initializers = {TestApplicationContextInitializer.class})
public class AppTest {
@Autowired
private ClientMapper clientMapper;
@Test
public void testInsert() {
Client client = new Client();
client.setName("test");
client.setRemark("lalal");
client.setCreatedAt(new Date());
client.setUpdatedAt(new Date());
clientMapper.insert(client);
System.out.println("lalalal");
}
}
在这个单元测试类里面我加上了自定义的initializer,方便引入外部的配置文件。