spring boot + hibernate + h2 搭建单元测试

场景

在开发中经常会遇到持久化层的单元测试,如果直接连 MySQL 那就需要本地提前安装好,并且在每个测试 case 上加回滚操作,这当然是能做到的,但终究有种很”重“ 的感觉。使用 H2 内存数据库,就可以实现随地单测,并且每个测试 case 执行完毕后 session 自动关闭,从而批量跑单测的时候(CICD)多个 case 之间不会相互影响。

所以搭建内存数据库用作持久化层的单元测试是很有必要的。

搭建

网上有很多这方面的博客,对对错错那就要靠自己踩坑甄别了,一番操作后做以记录。

  1. 添加依赖
<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>
  1. 配置
---
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
  1. 单元测试 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;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值