背景
最近在推团队单元测试的标准,其实任何依赖外部调用严格意义上都不算单元测试,但是数据库的SQL的正确性,的确是需要自测保证的,第一个版本就是本地初始化mybatis然后访问远程数据库,但这样容易影响测试数据库,因此本次考虑使用H2内存数据库进行测试。
H2分几种模式,其中内存数据库就是应用启动DDL表然后应用结束销毁所有,所以快捷轻量。
使用H2 + SpringBoot
首先pom文件
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
</dependency>
项目结构如图
UserDO
public class UserDO {
private Long id;
private String name;
// getter setter
// toString
UserMapper
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user")
List<UserDO> listUser();
}
启动主程序
@SpringBootApplication
public class H2DemoApplication implements CommandLineRunner
static {
System.out.println("start h2 test application");
}
public static void main(String[] args) {
new SpringApplication(H2DemoApplication.class).run(args);
}
@Autowired
private UserMapper userMapper;
@Override
public void run(String... args) throws Exception {
System.out.println("h2 app started");
List<UserDO> userDOS = userMapper.listUser();
System.out.println(userDOS);
}
}
application.yml
spring:
datasource:
driver-class-name: org.h2.Driver
schema: classpath:schema.sql #,每次启动程序,程序都会运行schema.sql文件,对数据库的数据操作
data: classpath:data.sql #,每次启动程序,程序都会运行data.sql文件,对数据库的数据操作
url: jdbc:h2:mem:test #配置h2数据库的连接地址
username: sa
password: sa
h2:
console:
enabled: true #开启web console功能
data.sql
DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
schema.sql
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
完成了,应用启动即可注入到UserMapper。输出打印
h2 app started
[UserDO{id=1, name='Jone'}, UserDO{id=2, name='Jack'}, UserDO{id=3, name='Tom'}, UserDO{id=4, name='Sandy'}, UserDO{id=5, name='Billie'}]
单元测试
单元测试是在test的目录下编写,如何读取到H2配置而不影响正常的数据库配置
需要引入的包和版本:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.197</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.4.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
在src/test/java下面编写测试用例,包括对应的Mapper包扫描。
@SpringBootTest(classes = {DataSourceAutoConfiguration.class, MybatisAutoConfiguration.class, MybatisConfiguration.class})
@RunWith(SpringRunner.class)
public class UserTest {
@Resource
private UserMapper userMapper;
@Test
public void test() {
List<UserDO> userDOS = userMapper.listUser();
System.out.println("h2 unit test running");
System.out.println(userDOS);
}
}
@Configuration
@MapperScan("com.micro.mapper")
class MybatisConfiguration {
}
data.sql和schema.sql文件写在test目录的resources下面,application.yml跟上面一样,其classpath会优先从main下面读,读取不到才会读test下面,所以不用担心对正常配置产生影响。
运行即可。