Daniel T. Daniel T. - 4 months ago 85
JSON Question

How do I unit test a Grails service that uses a converter?

I have a Grails service that sends out e-mails using a 3rd-party service by doing a HTTP call:

class EmailService {
def sendEmail(values) {
def valueJson = values as JSON
... // does HTTP call to 3rd party service
}
}


I've written a unit test to test this service (because an integration test spins up Hibernate and the entire domain framework, which I don't need):

@TestFor(EmailService)
class EmailServiceTests {
void testEmailServiceWorks() {
def values = [test: 'test', test2: 'test2']
service.sendEmail(values)
}
}


However, when I execute this unit test, it fails with this exception when it tries to do the
as JSON
conversion:


org.apache.commons.lang.UnhandledException: org.codehaus.groovy.grails.web.converters.exceptions.ConverterException: Unconvertable Object of class: java.util.LinkedHashMap


I then re-wrote my unit test to just do the following:

void testEmailServiceWorks() {
def value = [test: 'test', test2: 'test2']
def valueJson = value as JSON
}


And I get the same exception when it tries to do the
as JSON
conversion.

Does anyone know why I'm getting this exception, and how I can fix it?

Answer

The as JSON magic is created when the domain framework spins up.

You have to either change your test to an integration one or mock the asType.

def setUp(){
    java.util.LinkedHashMap.metaClass.asType = { Class c ->
        new grails.converters."$c"(delegate)
    }
}

Rember to clean up after yourself in the tearDown, you wouldn't want metaprogramming leaks in your test suite.

def tearDown(){
    java.util.LinkedHashMap.metaClass.asType = null
}