views:

133

answers:

3

I have a controller method like such:

def search = {
    def query = params.query

            ...

    render results as JSON
}

How do I unit test this? Specifically, how do I call search to set params.query, and how do I test the results of the method render? Is there a way to mock the render method, perhaps?

A: 

There are two ways to unit test the controller, but it will require some changes for you.

The first is to unit test the controller itself, without adding the complexity of http parsing, so you would write your unit test and pass in the params.query as part of your unit test, so, split your search function into two functions:

def search = {
  def query = params.query
  render realSearch(query) as JSON
}

def realSearch ...

So, the first part tests realSearch.

Then the second part is to write an application that will actually connect to your web application, and do a functional test, which will test your entire application, including the parts of the controller that wasn't tested in the first part.

James Black
A: 

TFM: Grails ref chapter 9

Follow the testCreateWithJSON() example ... just stuff your query string into params['query'], set the contentType, call search(). Since you're explicitly calling render, the esiest thing would be to look at the response.contentAsString ... I'd probably just make pattern-match asserts about the contentAsString; you could re-parse it as JSON and then examine that tree of objects, but I suspect that's not going to be as clear/quick as simple pattern-match assertions.

Wayne
+3  A: 

Subclass grails.test.ControllerUnitTestCase for your unit tests. Grails will automatically instantiate your controller and mock out versions of render and redirect that allow you to test the results easily. Just assign the test inputs to controller.params to set up the test.

Example:

class SomethingController {
    def search = {
        def query = params.query
        ...stuff...
        render results as JSON
    }
}

The test looks like:

class SomethingControllerTests extends grails.test.ControllerUnitTestCase {
    void testSearch() {
        controller.params.query = "test query"
        controller.search()
        assertEquals "expected result", controller.response.contentAsString
    }
}

Note: you can use ControllerUnitTestCase for integration tests too, if you need a full integration environment complete with database.

ataylor