简体   繁体   English

在 Spock 测试中调用 entity.delete(flush: true) 不会刷新,也不会使用 withTransaction,必须分别运行

[英]Calling entity.delete(flush: true) in a Spock test does not flush, nor does using withTransaction, one has to run both separately

I have a Grails 5.2.5 app with a Spock 2.0 test.我有一个带有 Spock 2.0 测试的 Grails 5.2.5 应用程序。 In it, I try to delete an entity like so:在其中,我尝试删除这样的实体:

def "experiment"() {
    given:
        MyEntity entity = new MyEntity().save(failOnError: true)).save(failOnError: true)
    when:
        entity.delete()
    then:
        MyEntity.count() == 0 // fails
}

It fails.它失败。 The saved entity stays there after the deletion attempt.保存的实体在删除尝试后保留在那里。 If I replace entity.delete() with any of the three options below, it still fails.如果我将entity.delete()替换为以下三个选项中的任何一个,它仍然会失败。

        MyEntity.withSession {
            entity.delete(flush: true, failOnError: true)
        }
// OR
        MyEntity.withTransaction {
            entity.delete(flush: true, failOnError: true)
        }
// OR
        entity.delete(flush: true, failOnError: true)

Or if I remove failOnError:true .或者,如果我删除failOnError:true

I am basically currently unable to delete stuff from DB during a spock test and I used to be able to do that in Grails 2.x, so not sure how to migrate those tests.我目前基本上无法在 spock 测试期间从数据库中删除内容,而我曾经能够在 Grails 2.x 中执行此操作,因此不确定如何迁移这些测试。

Edit:编辑:

I had managed to delete an entity like so, but it makes no sense to me, why these should work and the aboves not:我设法像这样删除了一个实体,但这对我来说毫无意义,为什么这些应该起作用而上面的不起作用:

def "experiment"() {
    given:
        MyEntity entity = new MyEntity().save(failOnError: true)).save(failOnError: true)
    when:
        entity.delete(flush: true) // here flush is necessary
        MyEntity.withTransaction {
            entity.delete()
        }
    then:
        MyEntity.count() == 0 // passes
}

and to my utter amazement this works as well even without the flush, whereas above the flush is necessary:令我非常惊讶的是,即使没有同花顺,它也能正常工作,而高于同花顺是必要的:

def "experiment"() {
    given:
        MyEntity entity = new MyEntity().save(failOnError: true)).save(failOnError: true)
    when:
        MyEntity.withTransaction {
            entity.delete()
        }
        entity.delete() // here flush is not necessary
    then:
        MyEntity.count() == 0 // passes
}

What source ry is this..这是什么源码。。

Alright, the problem was I only flushed the delete, not the save operation.好吧,问题是我只刷新了删除操作,没有刷新保存操作。 I thought I didn't have to since the saved entity was found during .count() operation.我认为我不必这样做,因为保存的实体是在.count()操作期间找到的。

Hibernate flushMode has COMMIT as default value instead of the AUTO from the past. Hibernate flushModeCOMMIT作为默认值,而不是过去的AUTO Documentation has an error on this, I posted a PR to fix the doc, the change was mentioned only in release notes, but doc wasn't updated .文档对此有错误,我发布了一个 PR 来修复文档,更改仅在发行说明中提到,但文档没有更新

Since that has changed, now that I want to save entities and delete them in tests, I need to flush both operations.由于已经改变,现在我想在测试中保存实体并删除它们,我需要刷新这两个操作。

So this works now okay:所以这现在可以正常工作了:

def "experiment"() {
    given:
        MyEntity entity = new MyEntity().save(failOnError: true, flush: true) // flush was added here that wasn't here before
    when:
        entity.delete(flush: true) // flush needs to be here as well.
    then:
        MyEntity.count() == 0 // works now
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM