Created
April 13, 2011 19:26
-
-
Save berngp/918221 to your computer and use it in GitHub Desktop.
ThrowableXMLMarshallerSpec.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.osscripters.grails.common.web.converters.marshaller | |
import grails.converters.XML | |
import org.codehaus.groovy.grails.web.converters.exceptions.ConverterException | |
import org.codehaus.groovy.grails.web.converters.marshaller.NameAwareMarshaller | |
import org.gcontracts.annotations.Requires | |
/** | |
* User: berngp | |
* Date: 4/12/11 | |
* Time: 2:48 PM | |
*/ | |
class ThrowableXMLMarshaller extends | |
ContextAwareObjectMarshallerTemplate<XML> implements NameAwareMarshaller { | |
boolean supports(Object object) { | |
object instanceof Throwable | |
} | |
@Requires({ supports(object) }) | |
void marshalObject(Object object, XML xml) throws ConverterException { | |
Throwable throwable = (Throwable) object | |
try { | |
xml.startNode('type').chars( throwable.class.name as String ).end() | |
xml.startNode('message').chars( getMessage(throwable.message) ?: throwable.message).end() | |
} | |
catch (ConverterException ce) { | |
throw ce | |
} | |
catch (anyOtherException) { | |
throw new ConverterException("Error converting Bean with class ${object.class.name}", | |
anyOtherException) | |
} | |
} | |
String getElementName(Object o) { | |
'error' | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.osscripters.grails.common.web.converters.marshaller | |
import grails.converters.XML | |
import grails.plugin.spock.ControllerSpec | |
import javax.servlet.http.HttpServletResponse | |
import org.codehaus.groovy.grails.support.MockApplicationContext | |
import org.codehaus.groovy.grails.web.converters.ConverterUtil | |
import org.codehaus.groovy.grails.web.converters.configuration.ConvertersConfigurationInitializer | |
import org.custommonkey.xmlunit.Diff | |
import org.slf4j.Logger | |
import org.slf4j.LoggerFactory | |
import org.springframework.validation.Errors | |
import org.springframework.web.context.WebApplicationContext | |
/** | |
* User: berngp | |
* Date: 4/12/11 | |
* Time: 2:48 PM | |
*/ | |
class ThrowableXMLMarshallerSpec extends ControllerSpec { | |
private static final Logger log = LoggerFactory.getLogger(ThrowableXMLMarshallerSpec) | |
def expectedMarkupTemplate = { Map args -> | |
"""<?xml version="1.0" encoding="UTF-8"?><error><type>${args.type}</type><message>${args.message}</message></error>""" | |
} | |
def applicationContext | |
def setup() { | |
mockApplicationContext() | |
registerDefaultConverters() | |
registerCustomConverters() | |
} | |
def 'marshall throwable'() { | |
given: 'a throwable that the controller will send' | |
controller.throwable = new IllegalStateException('Expected Message') | |
and: 'a expected xml that should be returned by the controller' | |
String expectedXml = expectedMarkupTemplate(type: controller.throwable.class.name, | |
message: controller.throwable.message) | |
when: 'we call the controller' | |
controller.testThrowable() | |
and: 'get the response' | |
String obtainedXml = mockResponse.contentAsString | |
and: 'build our xmlDiff object' | |
def xmlDiff = new Diff(obtainedXml, expectedXml) | |
then: 'we assert that the xmls are similar' | |
assert xmlDiff.similar(), "${obtainedXml} == ${expectedXml}" | |
} | |
def provideMvcClassUnderTest() { | |
TestController.class | |
} | |
protected WebApplicationContext mockApplicationContext() { | |
applicationContext = new MockApplicationContext() | |
applicationContext | |
} | |
protected void registerDefaultConverters() { | |
def convertersInit = new ConvertersConfigurationInitializer() | |
convertersInit.initialize() | |
[List, Set, Map, Errors].each { addConverters(it) } | |
} | |
protected void registerCustomConverters() { | |
//For unit testing add the a direct impl. of a Throwable, if not | |
//the metaclass is not cleaned properly after the test ends (cleanup). | |
addConverters(IllegalStateException) | |
XML.registerObjectMarshaller(new ThrowableXMLMarshaller()) | |
} | |
protected void addConverters(Class clazz) { | |
registerMetaClass(clazz) | |
clazz.metaClass.asType = {Class asClass -> | |
if (ConverterUtil.isConverterClass(asClass)) { | |
return ConverterUtil.createConverter(asClass, delegate, applicationContext) | |
} | |
else { | |
return ConverterUtil.invokeOriginalAsTypeMethod(delegate, asClass) | |
} | |
} | |
} | |
class TestController { | |
Throwable throwable | |
def testThrowable = { | |
response.status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR | |
withFormat { | |
xml { render throwable as XML } | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment