Question

I'm new in Grails and I'm doing some tests but although beforeUpdate and beforeInsert are called in development, my tests say they aren't, what I'm doing wrong?

I'm mocking Cicle and Measurement so I think that when the method save is called, the beforeUpdate or beforeInsert are triggered, but when I run the tests grails answers back saing "Too few invocations for: 1 * cicle.updateCicleValue() (0 invocations)"

So am I using the "when" incorrectly? or save doesn't trigger beforeUpdate and beforeInsert in mock objects?

Please help :)

Cicle.goovy

class Cicle {

String machine
double cicleValue

static hasMany = [measurements:Measurement]

def beforeInsert(){
    if (measurements != null) updateCicleValue()
}

def beforeUpdate(){
    if (measurements != null) updateCicleValue()
}

public void updateCicleValue(){

    double sumCicleValue = 0

    measurements.each{ measurement ->
        sumCicleValue += measurement.cicleValue
    }

    cicleValue = sumCicleValue / measurements.size()
}   
}

CicleSepc.groovy

@TestFor(Cicle)
@Mock([Cicle, Measurement])
class CicleSpec extends Specification {

Measurement mea1    
Measurement mea2    
Cicle cicle


def setup() {
    mea1 = new Measurement(machine: "2-12", cicleValue: 34600)      
    mea2 = new Measurement(machine: "2-12", cicleValue: 17280)      
    cicle = new Cicle(machine: "2-12")

    cicle.addToMeasurements(mea1)
    cicle.addToMeasurements(mea2)       
}

def cleanup() {
}

void "Test updateCicleValue is triggered"(){

    when: "Saving..."
    cicle.save(flush:true)

    then: "updateCicleValue is called once"
    1 * cicle.updateCicleValue()
}
}

Thanks!

Was it helpful?

Solution

//Integration Spec
import grails.test.spock.IntegrationSpec

class AuthorIntSpec extends IntegrationSpec {

    void "test something"() {
        given:
           def author

        when:
            Author.withNewSession {
                author = new Author(name: 'blah').save(flush: true)
            }

        then:
            author.name == 'foo'
    }
}

//Author
class Author {
    String name

    def beforeInsert() {
        this.name = 'foo'
    }
}

Also note, to use withNewSessionin events if you end up persisting any entity although above simple test would pass without specifying withNewSesion (mentioned for brevity).

In your use case, there is no mocking involved so testing an interaction is not possible afaik, but you can assert that the value of circleValue has updated after insert (flush), which in turn tests that beforeInsert event is fired appropriately.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top