grails / grails-testing-support

Trait-based testing library for Grails framework
http://testing.grails.org
Apache License 2.0
11 stars 21 forks source link

Calling flushing delete on an entity in a DataTest does not do it, nor when using withTransaction, one has to use both in and out. #259

Open mimkorn opened 1 year ago

mimkorn commented 1 year ago

Hi team.

I had created a minimal grails app repo demonstrating a persistence behavior in tests which I have difficulties understanding and am considering could possibly be erroneous. It can be run locally, but just reading the unit test should give a clear idea: Here's the unit test. https://github.com/mimkorn/Grails5-Strange-deletion-in-test-demo/blob/354e1bd361d6a55b98c5c37b60904c3377fba16a/src/test/groovy/grails5/strange/deletion/in/test/demo/ExampleSpec.groovy

Everything works as I would expect in Grails 2.5.6, which I am migrating from, but is not working in Grails 5.2.5. (the version of grails-testing-support used in my 5.2.5 project is 2.4.1)

mimkorn commented 1 year ago

I'm copying the code from the repo here, in case it helps get someone's attention.

// this is already weird, because FlushMode in Grails 5 is COMMIT by default, but the tests have AUTO by default.
def "Check that default FlushMode in tests is really AUTO"() {
    expect:
        currentSession.getFlushMode() == FlushModeType.AUTO // passes
}

// fails
def "simple deletion not working"() {
    given:
        def example = new Example().save()
    when:
        example.delete()
    then:
        Example.count() == 0 // this test fails, deletion doesn't happen, even though AUTO is used. Worked in Grails 2.5.6
}

// fails
def "flushing delete does not help"() {
    given:
        def saved = new Example(someProperty: "someText").save()
    when:
        saved.delete(flush: true)
        currentSession.flush()
    then:
        Example.count() == 0 // this test fails, deletion doesn't happen, even though I try to force flushing.
}

def "delete on a flush-saved entity works"() {
    given:
        def saved = new Example(someProperty: "someText").save(flush: true)
    when:
        saved.delete()
    then:
        Example.count() == 0
}

def "flush delete on a flush-saved entity works"() {
    given:
        def saved = new Example(someProperty: "someText").save(flush: true)
    when:
        saved.delete(flush: true)
    then:
        Example.count() == 0
}

def "update works"() {
    given:
        def saved = new Example(someProperty: "someText").save()
    when:
        saved.someProperty = "updatedValue"
    then:
        Example.findAll().first().someProperty == "updatedValue"
}

// fails
def "update suddenly does not work, if I attempt a deletion, even though deletion fails, but it affects that the update of value does not happen. Super confusing"() {
    given:
        def saved = new Example(someProperty: "someText").save()
    when:
        saved.someProperty = "updatedValue"
        saved.delete()
    then:
        Example.findAll().first().someProperty == "updatedValue" // fails, because the value has NOT updated to updatedValue, because deletion happened, which did not succeed? What?
        Example.count() == 0 // would also fail here, since deletion didn't happen.
}