Search code examples
grailsgroovygrails-orm

Grails domain validate keeps returning false positives for unit test


What I want: when I call validate (or save) on a parent domain during a unit test, it will check the constraints of all children domains AND their children AND their children etc.

What is happening: during a unit test for a service, validate keeps returning true despite constraints not being met for children domains. Please help...


Solution

  • I had two change two things about my code: 1) I had to make sure all domains were mocked for the unit test. 2) I had to make sure each child domain's back reference to the parent was populated. obj.addToSomeProperty(property) automatically populated back references for one-to-many objects, but for one-to-one I had to set it manually.

    Service Unit Test:

    @TestFor(GardenerService)
    @Mock([Orchard, Plot, Tree, Fruit])
    class GardenerServiceSpec extends Specification {
        void "test save and fetch"() {
            setup:
            Fruit fruit = new Fruit(name:"Peach")
            Tree tree = new Tree(height:6)
            tree.addToFruits(fruit)
            Plot plot = new Plot(litersOfWaterAdded:10)
    
            plot.tree = tree  // Must be a better way... why didn't setTree(tree) 
            tree.plot = plot  //   set the back reference
    
            Orchard orchard = new Orchard(orchardName:"Eden")
            orchard.addToPlots(plot)
    
            when:
            orchard.save(flush: true)
    
            then:
            orchard.validate()
            Fruit.findByName("Peach").tree.plot.orchard.name == "Eden"
            Tree.findByHeight(6).plot.litersOfWaterAdded == 10
        }
    }
    

    Domains:

    class Orchard {
        String orchardName
        static hasMany = [plots: Plot]
    }
    
    class Plot{
        static belongsTo = [orchard: Orchard]
        int litersOfWaterAdded
        static hasOne = [tree: Tree]
    }
    
    class Tree {
        static belongsTo = [plot: Plot]
        int height
        static hasMany = [fruits: Fruit]
    }
    
    class Fruit {
        static belongsTo = [tree: Tree]
        String name
        String description
    
        static constraints = { description nullable: true }
    }