要用集成 HibernateSpec 类,在 web profile 中执行测试很顺利,但在 plugin 中测试可能会失败。
这篇文章 对 grails service 测试方法进行了说明,但用于 plugin 时出现问题,例如在 plugin 中放了 domain、service,想用 unit test、integration test 对 domain、service 进行测试时,会报告错误。
典型的错误有:
- Not Domain class … GORM not initialized
- Table not found
尝试将 Service Spec 放到 plugin 的 integration-test 目录下,还是会报告 Table “VERIFY_CODE” not found 异常。
看来还是不能自动创建表。如何让 grails plugin 在测试前创建表呢?
我们来看看 web profile 项目,执行service单元测试时都做了哪些工作,让 service 的测试能正确。
web profile 的 service unit test 会在 test 库创建一个表。
最后发现是需要用 msyql 的 test 数据库,而不能用 h2database ,使用 h2database 会出现表找不到的问题,具体原因不明。
按照 web profile 项目的 datasource 配置、jar包依赖配置后,就可以在 plugin 中正确执行 hibernate service 单元测试了。
具体配置如下:
build.gradle
// 用不上 h2database 因为会导致表找不到的问题,具体原因不明
// runtime "com.h2database:h2"
testRuntime group: 'mysql', name: 'mysql-connector-java', version: '8.0.18'
// 测试 service 需要用 hibernate spec
testCompile "org.grails.plugins:hibernate5"
testCompile "org.hibernate:hibernate-core:5.4.0.Final"
application.yml
hibernate:
cache:
queries: false
use_second_level_cache: false
use_query_cache: false
dataSource:
pooled: true
jmxExport: true
driverClassName: com.mysql.cj.jdbc.Driver
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
configuration:
environments:
development:
dataSource:
dbCreate: create-drop
url: jdbc:mysql://localhost:3306/chess_develop?serverTimezone=GMT%2B8&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
username: chess_develop
password: "xxxx"
test:
dataSource:
dbCreate: update
url: jdbc:mysql://localhost:3306/chess_test?serverTimezone=GMT%2B8&autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
username: chess_test
password: "xxxx"
如上配置,在 plugin 中,也可以正确地执行 integration test 了。
总结
在普通 web profile 的grails 项目执行 service unit test 和 service integration test,按照官方的 guide 执行就可以,但要对 plugin 执行 service unit test、integration test 则需要使用 mysql datasource,要配置正确的 jar 包依赖。
单元测试还是很有用的,因为单元测试的执行速度快于集成测试,另外测试的范围比较集中,开发快。
集成测试适合测试整体逻辑,牵涉多个 service 的逻辑,或在在开发的最后阶段进行针对数据库访问的测试。