We have a custom data source that extends BasicDataSource. We have overridden the getConnection method which does a couple things inside of it. When we run the webapp outside of testing, when we call a service from a controller it will grab a new connection and use that connection until the 开发者_开发知识库service is done. All is well. However, inside an integration test, the connection appears to be grabbed before the test even calls the controller. Flow below
Regular Run: call controller -> controller calls service method -> connection is grabbed -> service method is run and returns to controller
Integration Test: connection is grabbed -> call controller from test -> controller calls service method -> service method is run and returns to controller
Needless to say, this is giving us problems as having the correct connection is very important for our app. Thoughts?
Edit: Still getting significant issues with this. We've reached a point where we have to avoid creating integration tests, or do some manual connection switching (which defeats half the point of the tests)
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'
}
This is not a final Answer, however I believe this is an explanation of what is going on:
Running as Web app: your Service class has a transactionManager which has a sessionFactory, which gets the connection! So in this case, assuming that you Service is 'transactional=true' all methods that you call in your services will have a 'Session.beginTransaction()' in the beginning of the method(there is a Grails`s Proxy to do that, when you set 'transactional=true'), which will call all that stack until getConnection().
Running as Integration Test: as Grails doesnt commit your DB changes, it always rollback them! I believe that when you are starting your Integration test, grails is creating a transaction right away! so it will be able to rollback it afterwards!(which make totally sense right!), you can confirm that taking a look at the class org.codehaus.groovy.grails.test.support.GrailsTestInterceptor. The method init() is called before your services in your integration test. So that`s why getConnection() is being called before everything!
Suggestion: You can try setting your integration test class as 'transaction=false' and see if getConnection() doesn't get call in the beginning! Go to Transactions section in here to see more! Just dont forget that in your test you will have to rollback your transaction! if your set transaction=false.
精彩评论