我们有一个扩展BasicDataSource的自定义数据源。我们已经覆盖了getConnection方法,该方法在其中执行了一些操作。当我们在测试之外运行webapp时,当我们从控制器调用服务时,它将获取新连接并使用该连接直到服务完成。一切都很好。但是,在集成测试中,连接似乎在测试甚至调用控制器之前被抓取。流程
常规运行: 呼叫控制器 - >控制器呼叫服务方法 - >连接被抓住 - >运行service方法并返回控制器
集成测试: 连接被抓住 - >来自测试的呼叫控制器 - >控制器呼叫服务方法 - >运行service方法并返回控制器
毋庸置疑,这给我们带来了问题,因为正确的连接对我们的应用非常重要。想法?
编辑:仍然遇到重大问题。我们已经达到了这样的程度,我们必须避免创建集成测试,或者进行一些手动连接切换(这会使测试的一半失败)
DataSource.groovy中
dataSource {
pooled = true
dialect="org.hibernate.dialect.OracleDialect"
properties {
maxActive = 50
maxIdle = 10
initialSize = 10
minEvictableIdleTimeMillis = 1800000
timeBetweenEvictionRunsMillis = 1800000
maxWait = 10000
testWhileIdle = true
numTestsPerEvictionRun = 3
testOnBorrow = true
}
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}
答案 0 :(得分:2)
这不是最终答案,但我相信这是对正在发生的事情的解释:
作为Web应用程序运行:您的Service类有一个transactionManager,它有一个sessionFactory,可以获得连接!所以在这种情况下,假设你的服务是'transactional = true',你在服务中调用的所有方法都会在方法的开头有一个'Session.beginTransaction()'(Grails的代理服务器就是这样做的) ,当你设置'transactional = true')时,它将调用所有堆栈直到getConnection()。
作为集成测试运行:由于Grails不提交数据库更改,它总是回滚它们!我相信,当您开始集成测试时,Grails会立即创建一个事务!所以它之后就可以回滚了!(这听起来很正确!),你可以确认看看班级org.codehaus.groovy.grails.test.support.GrailsTestInterceptor。方法init()在集成测试中的服务之前调用。这就是为什么在所有事情之前调用getConnection()的原因!
<强>建议强>: 您可以尝试将集成测试类设置为'transaction = false',并查看getConnection()是否在开始时没有调用! 转到here中的交易部分查看更多内容! 只是不要忘记,在您的测试中,您将不得不回滚您的交易!如果你的set transaction = false。