Grails 3 Integration Spec has Strange Transactional Behavior -


i have following test (which more of functional test integration but...):

@integration(applicationclass = application) @rollback class conventioncontrollerintegrationspec extends specification {    restbuilder rest = new restbuilder()   string url    def setup() {     url = "http://localhost:${serverport}/api/admin/organizations/${organization.first().id}/conventions"   }    def cleanup() {   }    void "test update convention"() {     given:     convention convention = convention.first()      when:     restresponse response = rest.put("${url}/${convention.id}") {       contenttype "application/json"       json {         name = "new name"       }     }      then:     response.status == httpstatus.ok.value()     convention.findbyname("new name").id == convention.id     convention.findbyname("new name").name == "new name"    } } 

the data being loaded via bootstrap (which admittadly might issue) problem when i'm in then block; finds convention new name , id matches, when testing name field, failing because still has old name.

while reading documentation on testing think problem lies in session data gets created in. since @rollback has session separate bootstrap, data isn't gelling. example, if load data via test's given block, data doesn't exist when controller called restbuilder.

it entirely possible shouldn't doing kind of test way, suggestions appreciated.

this functional test - you're making http requests against server, not making method calls , making assertions effects of calls.

you can't automatic rollbacks functional tests because calls made in 1 thread , they're handled in another, whether test runs in same jvm server or not. code in bootstrap runs once before of tests run , gets committed (either because made changes in transaction or via autocommit), , 'client' test code runs in own new hibernate session , in transaction testing infrastructure starts (and roll @ end of test method), , server-side code runs in own hibernate session (because of osiv) , depending on whether controller(s) , service(s) transactional or not, may run in different transaction, or may autocommit.

one thing not factor here should considered hibernate persistence tests session caching. hibernate session first-level cache, , dynamic finder findbyname trigger flush, want, should explicit in tests. won't clear cached elements , run risk of false positives code because might not loading new instance - hibernate might returning cached instance. when calling get(). add flushandclear() method integration , functional base classes , i'd put call after put call in when block sure flushed hibernate database (not committed, flushed) , clear session force real reloading. pick random domain class , use withsession, e.g.

protected void flushandclear() {    foo.withsession { session ->       session.flush()       session.clear()    } } 

since put happens in 1 thread/session/tx , finders run in own, shouldn't have effect should pattern used in general.


Comments

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -