[英]Table lock timeout when executing REST API functional test in Grails 2.4.4 using an in-memory H2 database
我正在嘗試使用funky-spock和rest-client-builder插件為我的REST API創建一組功能測試。
我的H2 DB連接字符串如下所示:
url = "jdbc:h2:mem:testDb:MVCC=true;LOCK_TIMEOUT=5000"
首先,我初始化h2數據庫,在setup()方法中引入一些記錄。 而且一切正常。
def setup() {
// Clean elasticsearch index
elasticSearchService.reinitialiseIndex()
// Initialize the DB
// 1st question
questionService.createQuestionFromOccurrence(
'181718e6-fd3b-4a1b-8b40-3f83fd2965e5',
QuestionType.IDENTIFICATION,
['kangaroo', 'grey'],
userMick,
'1st question 1st comment'
)
}
但是當我執行測試並執行POST請求時:
RestResponse response = rest.post("http://localhost:8080/${grailsApplication.metadata.'app.name'}/ws/question") {
json([
source : 'biocache',
occurrenceId: 'f6f8a9b8-4d52-49c3-9352-155f154fc96c',
userId : userKeef.alaUserId,
tags : 'octopus, orange',
comment : 'whatever'
])
}
該過程在第一個數據庫操作中失敗,在這種情況下,該數據庫操作為get()
,但以下情況除外:
ERROR errors.GrailsExceptionResolver - JdbcSQLException occurred when processing request: [POST] /taxon-overflow/ws/question
Timeout trying to lock table "QUESTION"; SQL statement:
看起來Grails測試中的所有數據庫操作都是在事務中執行的,該事務在每次測試后都會回滾。 顯然,它還鎖定了數據庫,並且由於REST請求將在與TEST分開的線程中執行,這意味着它無法訪問數據庫。 即使未鎖定,該進程也不會看到數據,因為它永遠不會提交。
進行此工作的一種方法是通過將屬性添加到測試中來使測試“不具有事務性”:
class RestAPISpec extends IntegrationSpec {
static transactional = false
...
}
這種方法的問題之一是,每次測試后,您都必須手動cleanup()
數據庫。 這是我發現的最簡單方法:
def grailsApplication
def sessionFactory
...
def cleanup() {
(grailsApplication.getArtefacts("Domain") as List).each {
it.newInstance().list()*.delete()
}
sessionFactory.currentSession.flush()
sessionFactory.currentSession.clear()
sourceService.init()
}
另一種方法是通過在集成測試中測試控制器來測試您的REST API,這也很麻煩,並且不是真正的Web服務端到端測試。 另一方面,它的執行比功能測試要快一些。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.