marco
marco

Reputation: 43

Test RestfulController with Grails

I'm trying to write some integration tests for a RestfulController in Grails 2.4.0 responding in JSON format. The index()-Method is implemented like this:

class PersonController extends RestfulController<Person> {
    ...
    def index(final Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond listAllResources(params), [includes: includeFields]
    }
    ...
}

The integration test looks like this:

void testListAllPersons() {
    def controller = new PersonController()
    new Person(name: "Person", age: 22).save(flush:true)
    new Person(name: "AnotherPerson", age: 31).save(flush:true)

    controller.response.format = 'json'
    controller.request.method = 'GET'

    controller.index()

    assertEquals '{{"name":"Person", "age": "22"},{"name":"AnotherPerson", "age": "31"}}', controller.response.json
}

What i don't understand is controller.response.json only contains the "AnotherPerson" instead of both entries. When i start the server with run-app und test it with a Rest-Client i get both entries. Any Ideas?

Upvotes: 4

Views: 2532

Answers (2)

marco
marco

Reputation: 43

I simplified the example a little too much. I used a named object marshaller which i created (incorrect) in bootstrap.groovy like this:

   JSON.createNamedConfig('simplePerson') { converterConfig ->
        converterConfig.registerObjectMarshaller(Person) {
            JSON.registerObjectMarshaller(Person) {
                def map = [:]
                map['name']  = it.name
                map['age']  = it.age
                return map
            }
        }
    }

And used it in the controller:

...
JSON.use("simplePerson")
...

The problem is solved by creating the object marshaller like this:

    JSON.createNamedConfig('simplePerson') { converterConfig ->
        converterConfig.registerObjectMarshaller(Person) {
            def map = [:]
            map['name']  = it.name
            map['age']  = it.age
            return map                
        }
    }

Upvotes: 0

Jeff Scott Brown
Jeff Scott Brown

Reputation: 27245

You haven't included enough information to say for sure what the problem is but the following test passes with 2.4.0.

The domain class:

// grails-app/domain/com/demo/Person.groovy
package com.demo

class Person {
    String name
    Integer age
}

The controller:

// grails-app/controllers/com/demo/PersonController.groovy
package com.demo

class PersonController extends grails.rest.RestfulController<Person> {

    PersonController() {
        super(Person)
    }

    def index(final Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond listAllResources(params)
    }
}

The test:

// test/unit/com/demo/PersonControllerSpec.groovy
package com.demo

import grails.test.mixin.TestFor
import spock.lang.Specification

@TestFor(PersonController)
@Mock(Person)
class PersonControllerSpec extends Specification {


    void "test index includes all people"() {
        given:
        new Person(name: "Person", age: 22).save(flush:true)
        new Person(name: "AnotherPerson", age: 31).save(flush:true)

        when:
        request.method = 'GET'
        response.format = 'json'
        controller.index()

        then:
        response.status == 200
        response.contentAsString == '[{"class":"com.demo.Person","id":1,"age":22,"name":"Person"},{"class":"com.demo.Person","id":2,"age":31,"name":"AnotherPerson"}]'
    }
}

Upvotes: 5

Related Questions