1

We recently upgraded from Grails 2.4.4 to 2.5.1 and also to JDK 8. Ever since that, the below test case has been failing.

In our service class, we have a private method defined to call an external service.

def retrieveResults() {       
    def results = callSoapService('serviceName')  
}

private def callSoapService(def serviceName) {     
    // call the service and format the results  
}

And in my spock test:

def setup() {
     service.metaClass.callSoapService = { String method -> mockSoapService(method) }
}

def "test service"() { 
    when: 
    def results = service.retrieveResults()

    then: 
    some value == results.size()
}

private mockSoapService(String method) {
    //mock the output
}

Basically over here, the private method is not getting mocked and the actual service is being called which is causing our test case to fail. Anybody has any pointers to mock a private method in Grails 2.5.1?

Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
raVan
  • 296
  • 2
  • 15
  • You have `String` in your metaMethods, but `def` in your service... Does `service.metaClass.callSoapService = { method -> mockSoapService(method) }` work? – tim_yates Sep 25 '15 at 14:32
  • Tried it, doesnt work – raVan Sep 25 '15 at 14:43
  • I would like to challenge the reasons behind writing this unit test. Even if you achieve what you want, you will just test a mocked method. That test will always pass and it adds no value to your project. Does the retrieveResults() method has more code not shown here? – kazanaki Sep 30 '15 at 13:11

1 Answers1

0

When I have problems with mocks using metaclass, I use this and usually solve the problem:

private MetaClassRegistryCleaner registryCleaner = MetaClassRegistryCleaner.createAndRegister()

void setup() {
    GroovySystem.metaClassRegistry.addMetaClassRegistryChangeEventListener(registryCleaner)
}

void cleanup() {
    registryCleaner.clean()
    GroovySystem.metaClassRegistry.removeMetaClassRegistryChangeEventListener(registryCleaner)
}
jpozorio
  • 622
  • 6
  • 7