1、场景
在写DAO层的单元测试时,我们往往会遇到一个问题,测试用例所依赖的数据库数据被修改或删除了,或者在一个新的环境下所依赖的数据库不存在,导致单元测试无法通过。在这种情况下,使用H2内存数据库来模拟数据库环境是一个很好的解决方案。
2、H2 特点
使用maven工程来搭建测试环境,工程目录如下:
1、核心依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> </dependencies> |
2、配置文件 application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
server: port: 18095 spring: application: name: service-h2 jpa: show-sql: true #打印sql datasource: url: jdbc:h2:mem:xwj_db;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE #mem:连接到内存 driver-class-name: org.h2.Driver username: root password: 123456 data: classpath:db/data.sql #初始化表数据 |
参数说明:
3、实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@Entity @Getter @Setter @ToString @NoArgsConstructor public class XwjUser implements Serializable { private static final long serialVersionUID = -2169427939264532306L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; /** 名称 */ public String name; /** 年龄 */ private Integer age; private Date createDate; } |
4、Repository
1 2 3 |
public interface UserRepository extends JpaRepository<XwjUser, Long>{ } |
5、Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
@Service public class UserService { @Autowired private UserRepository userRepository; @Autowired private JdbcTemplate jdbcTemplate; public List<XwjUser> findAll() { return userRepository.findAll(); } public XwjUser save(XwjUser user) { return userRepository.save(user); } /** * 通过主键id查询 */ public XwjUser findById(Long id) { Optional<XwjUser> optional = userRepository.findById(id); if (optional.isPresent()) { return optional.get(); } return null; } /** * 通过名称查询 */ public List<XwjUser> findByName(String name) { String sql = "select * from xwj_user where name like ?"; Object[] paramArr = new Object[1]; paramArr[0] = name + "%"; return jdbcTemplate.query(sql, paramArr, new BeanPropertyRowMapper<>(XwjUser.class)); } } |
1、在 src/main/resources 目录下,创建一个目录 /db 和脚本文件 data.sql :
1 2 3 4 5 |
insert into xwj_user (id, name, age, create_date) values(11,'张三','12','2020-04-17 00:00:00'); insert into xwj_user (id, name, age, create_date) values(12,'李四','13','2020-04-17 00:00:00'); insert into xwj_user (id, name, age, create_date) values(13,'王五','25','2020-04-17 00:00:00'); insert into xwj_user (id, name, age, create_date) values(14,'赵六','17','2020-04-17 00:00:00'); insert into xwj_user (id, name, age, create_date) values(15,'吉米','30','2020-04-17 00:00:00'); |
2、在 src/test/java 目录下,创建一个测试类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
@RunWith(SpringRunner.class) @SpringBootTest public class H2Test { @Autowired private UserService userService; /** * 测试查询所有 */ @Test public void testFind() { List<XwjUser> list = userService.findAll(); System.out.println("list: " + list); } /** * 测试新增+查询 */ @Test public void testInsertAndFind() { // 1、新增 XwjUser user = new XwjUser(); user.setAge(19); user.setName("张三"); user.setCreateDate(new Date()); XwjUser newUser = userService.save(user); // 2、通过id查询 Long id = newUser.getId(); System.out.println("findById: " + userService.findById(id)); // 3、模糊查询(自定义sql) String name = "张"; System.out.println("findByName: " + userService.findByName(name)); } } |
3、测试 H2Test#testFind 方法,日志如下:
4、测试 H2Test#testInsertAndFind 方法,日志如下:
1、在配置文件不要配置 schema,也不要直接将 schema.sql 脚本直接放在 src/main/resources 目录下,否则初始化数据脚本(即上面的data.sql)不会生效。
问题现象:执行方法的过程中没有任何报错,schema 和 data 脚本都会被执行(故意写错脚本会抛出异常)
问题原因:待进一步分析
from:https://www.cnblogs.com/xuwenjin/p/14829316.html