spring boot + hibernate + h2 搭建单元测试
场景在开发中经常会遇到持久化层的单元测试,如果直接连 MySQL 那就需要本地提前安装好,并且在每个测试 case 上加回滚操作,这当然是能做到的,但终究有种很”重“ 的感觉。使用 H2 内存数据库,就可以实现随地单测,并且每个测试 case 执行完毕后 session 自动关闭,从而批量跑单测的时候(CICD)多个 case 之间不会相互影响。所以搭建内存数据库用作持久化层的单元测试是很有必要的
·
场景
在开发中经常会遇到持久化层的单元测试,如果直接连 MySQL 那就需要本地提前安装好,并且在每个测试 case 上加回滚操作,这当然是能做到的,但终究有种很”重“ 的感觉。使用 H2 内存数据库,就可以实现随地单测,并且每个测试 case 执行完毕后 session 自动关闭,从而批量跑单测的时候(CICD)多个 case 之间不会相互影响。
所以搭建内存数据库用作持久化层的单元测试是很有必要的。
搭建
网上有很多这方面的博客,对对错错那就要靠自己踩坑甄别了,一番操作后做以记录。
- 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
- 配置
---
spring:
profiles: unit-test
jpa:
open-in-view: true
properties:
hibernate:
enable_lazy_load_no_trans: true
hibernate:
ddl-auto: create
globally_quoted_identifiers: true
show-sql: true
database-platform: org.hibernate.dialect.H2Dialect
datasource:
platform: h2
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:testDB;DB_CLOSE_DELAY=-1;MODE=LEGACY
- 单元测试 demo
@SpringBootTest
@ActiveProfiles("unit-test")
class JpaApiLogRepositoryTest {
@Autowired
private JpaApiLogRepository jpaApiLogRepository;
@Test
void should_save_api_log_succeed() {
ApiLog apiLog = TestFigure.getApiLog("diego2", "/api/v1/nlp/test/", "GET");
jpaApiLogRepository.save(apiLog);
Optional<ApiLog> optional = jpaApiLogRepository.findById(apiLog.getId());
assertThat(optional.isPresent(), is(true));
ApiLog fetched = optional.get();
assertThat(fetched.getId(), is(notNullValue()));
assertThat(fetched.getTraceId(), is(apiLog.getTraceId()));
assertThat(fetched.getMethod(), is(apiLog.getMethod()));
assertThat(fetched.getPath(), is(apiLog.getPath()));
assertThat(fetched.getRequestParams(), is(apiLog.getRequestParams()));
assertThat(fetched.getRequestBody(), is(apiLog.getRequestBody()));
assertThat(fetched.getResponseStatus(), is(apiLog.getResponseStatus()));
assertThat(fetched.getRequestTime().getTime(), is(apiLog.getRequestTime().getTime()));
assertThat(fetched.getResponseTime().getTime(), is(apiLog.getResponseTime().getTime()));
assertThat(fetched.getTimeUsed(), is(apiLog.getTimeUsed()));
assertThat(fetched.getRemark(), is(apiLog.getRemark()));
}
}
小问题
有时候会遇到 h2 不支持一些 sql 语法,这时就需要见招拆招,具体问题具体对待了。有一种场景是:sql 中的字段命中了 h2 的关键子导致执行失败。比如:
@Entity
@Data
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private int order;
}
order
是 h2 的关键字, 报异常org.hibernate.exception.SQLGrammarException: could not prepare statement
。
解决办法:
@Column(name = "`order`")
private int order;
更多推荐
已为社区贡献5条内容
所有评论(0)