lundi 2 mars 2015

Grails 2.4.4 : How do mock a transient service inside a domain?

I have been trying to figure this out for 2 days now and I am really stuck and frustrated. I have a domain object with a service which is being used for custom validation. The domain looks like this:



class Llama {
String name
transient myFetcherService

static transients = [
'myFetcherService'
]

static constraints = {
name validator: { val, obj ->
if (obj.nameExists(val) == true) {
//return some error here.
}
}
}

protected boolean nameExists(String name) {
List<Llama> llamasList = myFetcherService.fetchExistingLlamasByName(name)

if (llamasList.isEmpty()) {
return false
}

return true
}
}


Now, I have another Service, which simply saves a list of Llama objects. It looks like this:



class LlamaFactoryService {

public void createLlamas(List<String> llamaNames) {
llamaNames.each { name ->
new Llama(name: name).save()
}
}

}


In my test. I keep getting this error:



Failure: createLlamas should create Llammas (com.myLlamaProject.LlamaFactoryServiceSpec)
| java.lang.NullPointerException: Cannot invoke method myFetcherService on null object


I don't understand. In my tests, added a metaClass for the service in the "given" section. When it tries to save, it's telling that the service is null. This is what my test looks like:



given:
def myFetcherService = mockFor(MyFetcherService)
myFetcherService.demand.fetchExistingLlamasByName {def name -> return []}
Llama.metaClass.myFetcherService = myFetcherService.createMock()

when:
service.createLlamas(['Pablo','Juan','Carlos'])

then:
//some validations here....


I also tried using metaClass on the method nameExists(), but it gives me the same nullPointerException as the one above. Could someone point me to the right direction? I'm a bit stuck. :(


Thanks in advance for reading and helping.


Aucun commentaire:

Enregistrer un commentaire