在实施每日构建的开发团队中,通常都会要求进行自动化的单元测试和功能测试。在数据库类型的应用中,功能测试的难点就是对数据的准备。本文介绍一种通过H2 内存数据库来进行功能测试的方法。
环境说明
在本示例中,分别采用了如下一些软件版本:
Spring Boot: 2.2.5
JUnit: 5.2.0
案例以一个简单的登录服务(Rest Service)为案例。 用户提供用户名和密码,如果验证成功,服务放回登录凭证(token), 如果是非法yoghurt,则返回错误信息。
Spring Boot 服务的基本构建可以参考 Spring Boot 构建Rest服务实验手册(一),本文主要展示项目构建好以后如何借助H2数据库实施自动化的功能测试。
准备依赖库
因为要使用 H2 作为测试库,所以需要在项目中添加 H2 的依赖项, 在 pom.xml 文件中加入:
1 | <dependency> |
在 Spring Boot 2.2.5 版本中生成的 pom.xml 文件中,默认是使用 JUnit 4 的版本,要替换为 JUnit 5,需要做如下的改动。
- 排除(exclusions) spring-boot-starter-test 中已有的 JUnit4
1 | <dependency> |
- 添加 JUnit 5的以来项
1 | <dependency> |
- 为了能在 Maven 命令行中执行(每日构建中需要)测试,需要添加正确的 plugin:
1 | <plugin> |
准备 H2 测试数据库和测试数据
- 在 src/test/resources 中添加名为 application.yml 的文件,内容如下:
1 | spring: |
该配置指定在测试中使用内存数据库,这样可以比较简单的处理测试数据。
- 在 data.sql 文件中准备数据。
在 src/test/resources 中添加名为: data.sql 的文件。使用 SQL 语句构建测试数据,比如在本例中就可以简单的加入如下的 SQL 语句:
1 | insert into Account_Bean (id, name, pwd) values (1, 'tom', '123'); |
对应的实体对象为:
1 |
|
编写测试案例
对于登录功能,我们在Web服务层实现如下代码:
1 |
|
注意: 这里返回的 LoginResult 对象会被拦截器统一转换为 ApiResult 的格式
正确登录的案例
在 src/test/java 相应的包中添加测试类 SecurityApiTest: 代码如下:
1 | .class) (SpringExtension |
可以看到,我们用 JUnit5 中新的 ExtendWith 代替了 JUnit 4 中的 RunWith, 并使用了 SpringBoot 中的 SpringExtension 类。
在测试案例中,我们没有使用 Mock 对象,而是通过 TestRestTemplate 对象直接访问启动的 Spring Boot 服务, 服务的执行也是直接通过原有的代码访问数据库,最大限度的模拟的用户的操作。
验证是否将 token 记录在数据库中
在真是的系统中,不但要将生成的用户凭证(token)发给用户,也需要将 token 写入到数据库中,对于写入的结果,我们也可以在案例中进行测试。修改测试代码如下:
1 |
|
可以看到,我们增加了 AccountBean 对于的数据访问对象 AccountRepos, 用来直接操作数据库。然后再代码中通过 findById 的方式找到数据库中的记录,并验证 token 是否存在。当然也可以进一步验证 Token 值。
测试登录不成功的情况
用以下代码,可以验证当输入的密码错误时的情况。
1 |
|
与正确的情况相比,主要是验证结果为 False,错误码为特定的,定义好的错误码。