0

I have a domain class called Provenance that is used to mark records created by the application vs other creation methods (ETL, etc...). The record pre-exists in the DB and beforeInsert, beforeUpdate, beforeDelete throw a RuntimeException to enforce the domain being read-only

class Provenance implements Serializable {
    ...
    static Provenance MANUAL() {
        findByProvenanceType('MANUAL')
    }

    def beforeInsert() {
        throw new RuntimeException('create not allowed')
    }
    ...
}

I'm testing a service method that saves a Person (mockDomain) record. I had mocked this like so:

given:
def provenance = GroovyMock(Provenance, global: true)
...
when:
def result = service.savePerson(params)
...
then:
1 * Provenance.MANUAL() >> provenance
result.person.provenance == provenance

The primary change for the migration is 2.3.4 used @Mock for the Person domain vs mockDomain for 3.3.8.

This worked fine for grails 2.3.4. But when migrating to grails 3.3.8, saving the person cascades to the Provenance which causes the RuntimeException from beforeInsert to be thrown.

I also thought about using mockDomain on Provenance and saving it beforehand, but I have the same issue because beforeInsert can't be overridden to prevent the RuntimeException. Any thoughts on why this would change between versions and how to work around it?

John
  • 27
  • 1
  • 9
  • I expect that you don't have the test configured such that the Hibernate events are fired. – Jeff Scott Brown Nov 30 '18 at 19:45
  • I set breakpoints on the Hibernate events on the Person and Provenance classes and the events are fired on the Person in 2.3.4 and 3.3.8. The difference is that it doesn't fire the Provenance.beforeInsert when the Person is saved in 2.3.4, but it does in 3.3.8, so it seems like the save doesn't cascade in 2.3.4 but does in 3.3.8. Note Provenance was not included in @Mock or mockDomain, just GroovyMock – John Nov 30 '18 at 20:19

1 Answers1

0

following advice from ice1080 in Overriding event closure on Grails GORM domain class for unit testing, I moved the logic in beforeInsert to another method and overrode that method in the test to allow the domain to be created during setup

John
  • 27
  • 1
  • 9