Share

August 12, 2010

Grail REST WebService is easy and painful

Grails: 1.3.3 I been creating a simple webserivce and it is great but I can't test it... here is what i have...

Simple Controller
class PlayerNameController  {
  private def logger = Logger.getLogger(getClass());

  static defaultAction = "retrieve"

  def retrieve = {
    logger.info "starting retrieve"
    def name = params.name
    wsRender new PlayerNameResponse(name: name)
  }

  protected void wsRender(object) {
    String reqContentType = request.contentType;
    logger.debug "Response requested in ${reqContentType} format"

    if (reqContentType != null && 
             MediaType.APPLICATION_JSON == MediaType.parseMediaType(reqContentType)) {
      logger.debug "render in json"
      render object as JSON
    } else {
      logger.debug "render in xml"
      render object as XML
    }
  }
}

When i test via my IDEA REST Client it works great.... but... there is always a but... when i create my unit test i get strange errors

class PlayerNameControllerTests extends ControllerUnitTestCase {

  void testJSON() {
    
    controller.params.username = "my name"
    controller.request.contentType = "application/json"
    controller.retrieve()
    assertEquals HttpStatus.OK.value, controller.response.status
    assertTrue StringUtils.hasText(controller.response.getContentAsString()) 
  }
I get the following strange error
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'abcClass@62803d5' with class 'abcClass' to class 'grails.converters.XML'

if i change the Controller to the unit test pass but i don't get any body in my response...
protected void wsRender(object) {
    String reqContentType = request.contentType;
    logger.debug "Response requested in ${reqContentType} format"

    if (reqContentType != null && 
             MediaType.APPLICATION_JSON == MediaType.parseMediaType(reqContentType)) {
     logger.debug "render in json"
      render(contentType: "application/json") {
        object
      }
    } else {
      logger.debug "render in xml"
      render(contentType: "application/xml") {
        object
      }
  }

if you think you can help please... I like i like grails but it is very strange when groovy does stuff like that. thanks George

6 comments:

  1. Does it work any better if you use an integration test rather than a unit test? Remember that for unit tests you don't get all the dynamic finders and some other treats that you get with integration tests... Worth a try to see.

    ReplyDelete
  2. You can't use unit tests as they don't support json or xml rendering when i last looked. If you want to do rest with Grails, use the jax-rs plugin, it is *really* easy and really much, much better than what Grails itself provides. *much*

    ReplyDelete
  3. In unit tests, you can call addConverters(abcClass) from your test case to enable the "as XML" syntax.

    ReplyDelete
  4. pledbrook, wow... you are correct that does it... but looking at that method src it has no docs... how did you find it...

    I'll post a blog about how to test Grails REST WS :D

    thanks a lot... One less Grails gotcha to worry about.

    ReplyDelete
  5. I am the guilty party that wrote it. Undocumented, yes. In fact, we recognise that the whole testing side of things needs more docs.

    ReplyDelete
  6. I'll make sure to post a blog about how it test my Grail REST WS where i use everything i learned and your hint.

    George

    ReplyDelete