使用h2database对java关系数据库访问逻辑进行测试

1 单元测试的基本原则

  • Air原则:Automatic(自动化)、Independent(独立)、Repeatable(可重复)。即单元测试应该是全自动执行的,不需要依赖人工去交互触发执行、检查。其次为了保持稳定可靠且易维护,单元测试用例之间不能相互调用且执行不受先后次序影响。最后就是可重复执行,通过断言判断,可以重复对测试结果验证。
  • BCDE原则
    • Border:边界测试,包括循环、 特殊取,边界值测试包括循环、 特殊取特殊时间点、数据顺序等。
    • Correct:给出正确的输入,并得到预期结果。
    • Design:与设计文档相结合,来编写单元测试。
    • Error:强制提供错误信息输入(如:非法数据、异常流程业务允许等),并得到预期错误验证结果。

2 数据库访问的测试测试方法

  • 搭建单测环境测试:测试环境专门创建一个单测库,并进行相关配置,最终进行测试。这种方式的优点是减少环境依赖,并对数据进行mock。但也存在缺点,种方式转换为依赖特定的单测库,可能有某些原因库中数据被修改,导致测试用例不稳定。此外依赖外部调用(对远程数据库访问),脱离相关环境,单测无法执行。
  • 直接mock数据访问层接口:这种方式直接通过Mockito框架mock接口,使测试可以保持独立,但Sql逻辑无法得到验证。
  • 使用内存数据库:这种方法避免了对外部环境依赖,使测试独立稳定,但内存数据库和系统中使用的关系数据库存在差异,例如关键字、语法等。这样需要再次解决这些问题。

数据访问层的核心就是sql,因此逻辑正确性也必须验证。通过对比看,第三种方式满足诉求。

3 H2database简介

h2database是一个用Java编写的嵌入式关系型数据库管理系统,可以在内存中运行。h2database支持标准的SQL语法和JDBC API。此外h2database还具备下列特点:

  • 高性能:采用了高效的算法和数据结构,具有出色的性能。
  • 轻量:的代码量非常小,可以很容易地嵌入到应用程序中,同时也支持多种部署方式。
  • 兼容性强:支持标准的SQL语法和JDBC API,同时也支持多种数据库的兼容模式。
  • 可靠性高:采用了事务机制和数据持久化技术,可以保证数据的一致性和可靠性。
  • 使用简介:提供了丰富的文档和示例,可以很容易地上手使用。

4. Spring Boot中使用h2database

添加依赖

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-jpaartifactId>
dependency> 
<dependency>
    <groupId>com.h2databasegroupId>
    <artifactId>h2artifactId>
dependency>
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-testartifactId>
dependency>

src/test/resources/application.properties文件下增加配置属性

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

此外可以将属性单独配置在一个属性文件中。例如在src/test/resources/persistence-generic-entity.properties文件下单独配置h2db的属性。

jdbc.driverClassName=org.h2.Driver
jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
jdbc.username=sa
jdbc.password=sa

在单测中写测试,如果我们对h2db使用了单独的测试文件,那么单测中需要通过注解引入配置。
我们先定义配置:

@Configuration
@EnableJpaRepositories(basePackages = "org.baeldung.repository")
@PropertySource("persistence-generic-entity.properties")
@EnableTransactionManagement
public class H2JpaConfig {
    // ...
}

单测中引入配置

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class, H2JpaConfig.class})
public class SpringBootH2IntegrationTest {
    // ...
}

如果没有单独使用配置文件,那么按如下方式配置即可

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class SpringBootJPAIntegrationTest {
 
    @Autowired
    private GenericEntityRepository genericEntityRepository;

    @Test
    public void givenGenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() {
    }
}

5.通过web控台访问h2database

在前文介绍的配置文件中增加配置

spring.h2.console.enabled=true

接着启动系统,通过http://localhost:8080/h2-console打开控制台。 8080端口是设置的http端口。
使用h2database对java关系数据库访问逻辑进行测试_第1张图片
接着输入前文中配置的用户名密码后就可以进入后台看到数据。
使用h2database对java关系数据库访问逻辑进行测试_第2张图片

6 org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement错误处理

遇到这种情况是mysql语法与h2db有差异,此时如果使用idea,可以使用 「MySql To H2」这个插件进行转换,随后就能得到可执行的SQL。
使用h2database对java关系数据库访问逻辑进行测试_第3张图片

7 UnboundConfigurationPropertiesException c[1].mapperlocations] were left unbound出错处理

遇到这个问题是配置文件中为了配置多套属性,使用了数组的方式配置

c[1].p1=xxx
c[1].p2=xxx

但在一个属性文件中,这种方式下标从0开始,必须连续。因此调整为c[0].p1。如果后续再有配置,连续配置即可 c[1].p1 ,… c[n].p1 届。

参考

[1].https://www.baeldung.com/spring-testing-separate-data-source
[2].https://www.baeldung.com/spring-boot-h2-database

你可能感兴趣的:(工程质量,java,开发语言,单元测试)