Search code examples
grailsmockinggrails-ormgeb

Trouble mocking a domain when migrating from grails 2.3.4 to 3.3.8


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?


Solution

  • 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