blog community
Testing Grails REST services

Unit Testing in Grails is very easy. If you are not familiar with this, you should definitely check out the reference manual about it. Today however, I was writing some REST services that return XML. The controller does content negotiation and can, depending on the request, return HTML or XML. Of course I also wanted to write a test for it, but I couldn't find how to do it in the documentation. It turns out to be very easy, but I wanted to share how I did it.

First a simple version of a controller that supports content negotiation: 

def list = {
    def myContact = new Contact(firstname: 'Paul', lastname: 'Bakker')

    withFormat {
      html {
        [contact: myContact]      
      }

      xml {
        render(contentType: "application/xml") {            
            contact {
              firstname(myContact.firstname)
              lastname(myContact.lastname)
            }
        }
      }
    }
  }

The withFormat block chooses, depending on the request, the response to build. If this controller is requested with a normal URL from a browser, HTML will be returned. If the Accept header is set, or if the URL is postfixed '.xml', XML will be returned however. This is all documented well in the reference documentation, so you can read the details there. If the controller is requested for XML, the following XML will be returned:

<contact>
   <firstname>Paul</firstname>
   <lastname>Bakker</lastname>
</contact>

 

Next I wanted to write a Unit Test for this controller. There are two special things about testing a controller that does content negotiation:

  1. Request the correct content type
  2. Test if the response is generated correctly

For the first step you should first understand how the controller figures out what content type to return. When Grails processes a request, it will check both the Accept header and the URL extension (note that the Accept header is not enabled by default!). It will set a variable request.format with the value that is defined in the mime.types configuration in Config.groovy for that request format. So concluding, you'll need to set the request.format variable in the test, which is very easy. 

controller.request.format = 'xml'

Note that the controller variable in the example is the implicitly created controller by the ControllerUnitTestCase.

Next you should invoke the controller and check the XML returned by the controller. This is what I couldn't find in the documentation. After invocation you can access the response using:

controller.response.getContentAsString()

This contains the XML as a String, which you can parse using XmlParser. Easy! The complete test is displayed below. Note that only the XML request is tested. You should add another test to test the HTML response.

void testListInXML() {
    controller.request.format = 'xml'

    controller.list()

    def contact = new XmlParser().parseText(controller.response.getContentAsString())
    assert contact.firstname.text() == 'Paul'
    assert contact.lastname.text() == 'Bakker'

  }

Posted 20-08-2009 17:06 by Paulb
Filed under: ,

Comments

where is the REST???? wrote re: Testing Grails REST services
on 20-08-2009 21:09

So...this is really on how to send a format to a controller in a test...not really how to test a REST service???

Paulb wrote re: Testing Grails REST services
on 20-08-2009 22:33

It's a simplified example. The example controller is not a REST service, it just returns XML, but a full blown service can be tested the same way. It would just be more code.

gphreak wrote re: Testing Grails REST services
on 21-08-2009 14:51

I wonder why people using punctuation marks in large packs always end up to be idiots.

Nice example, Paul, thanks.

Just one punctuation mark this time. - Nick wrote re: Testing Grails REST services
on 21-08-2009 16:39

Paul,

Sorry to come across snarly in the first post.

Thank you for your example.  How to test sending / expecting different formats will come in helpful when testing my controllers (RESTful or not).

The point I was trying to make was that the article is titled "Testing Grails REST services", but does nothing as far as testing anything RESTful.  When people are trying to learn about RESTful services, and they come across an article like this, they will believe that all a RESTful service means is that it can do some sort of content negotiation.

I just had a lost feeling after reading, and felt a buzzword was used to get attention to the article.  There is far to much of that out here.

But again, thank you, and sorry again for the first post coming across like that, should have probably waited to post or not posted anything at all.

-- Nick

Stephane wrote re: Testing Grails REST services
on 19-09-2009 15:35

It'd be nice if the example showed how to unit test this RESTful GET request for example:

curl --request GET --header "Content-Type: text/xml" localhost/.../1

Steve Dalton wrote re: Testing Grails REST services
on 30-11-2009 23:48

Thanks Paul

The controller.response.getContentAsString bit was just what I was looking for.

Steve

Add a Comment

(required)  
(optional)
(required)  
Remember Me?
Enter code (required)
Powered by Community Server (Commercial Edition), by Telligent Systems