Grails / Spock: How to mock single method within class where method is called from within the class itself?

John picture John · Dec 12, 2014 · Viewed 17.3k times · Source

Given the following, how do I mock processMessage() using Spock, so that I can check that processBulkMessage() calls processMessage() n times, where n is the number of messages within a BulkMessage?

class BulkMessage {
    List messages
}

class MyService {

    def processBulkMessage(BulkMessage msg) {
        msg.messages.each {subMsg->
            processMessage(subMsg)
        }
    }

    def processMessage(Message message) {

    }
}

Answer

Gregor Petrin picture Gregor Petrin · Dec 12, 2014

You can use spies and partial mocks (requires Spock 0.7 or newer).

After creating a spy, you can listen in on the conversation between the caller and the real object underlying the spy:

def subscriber = Spy(SubscriberImpl, constructorArgs: ["Fred"])
subscriber.receive(_) >> "ok"

Sometimes, it is desirable to both execute some code and delegate to the real method:

subscriber.receive(_) >> { String message -> callRealMethod(); message.size() > 3 ? "ok" : "fail" }