Neoecos
Neoecos

Reputation: 579

How to test compound json object response in a controller within grails 2.4.3

I am testing the save method of a Restful controller, the CustomerController.

The Customer, the domain class, has an Address association, Address has a City, a City has a State, and a State has a Country.

I wrote custom marshallers and a custom binding helper for Address, so a JSON Customer is like this:

{
    "id": "g2c3e08iqton4v5bsgti33gkpd35l0er",
    "firstName": "Bob1",
    "lastName": "Patiño1",
    "middleName": "The Payaso1",
    "email": "[email protected]",
    "phoneNumber": "300555551",
    "address": {
        "addressLine1": "addressLine1",
        "postalCode": "110111",
        "city": {
            "name": "Bogotá",
            "state": "DC",
            "country": "CO"
        }
    }
}

Everything is working using that format, remember the custom marshallers and binding helper for Address, but now I want to test the controller.

 @Unroll
 void "create a new customer firstName: #firstName"(){
        when: 'the merchantUser requests to create a new Customer'
        controller.request.method = 'POST'
        controller.request.contentType = JSON_CONTENT_TYPE
        controller.request.JSON = [
            firstName: firstName, lastName : lastName, middleName:middleName,
            gender: gender, email: email, phoneNumber: phoneNumber, address: address
        ]
        controller.save()

        then:'The response code should be CREATED (201)'
        controller.response.status == 201

        and: 'The new customer should be returned'
        controller.response.json.firstName == firstName
        //TODO How to validate the address is added?
        //controller.response.json.address == ????
        1 * controller.springSecurityService.getPrincipal() >> merchantUser

        where:
        firstName|lastName|middleName|gender|email|phoneNumber|address
        JSONObject.NULL     |JSONObject.NULL    |JSONObject.NULL      |JSONObject.NULL  |JSONObject.NULL |JSONObject.NULL|JSONObject.NULL
        'bob'    |'patiño'|'de'      |'M'   |'[email protected]'| '20055555'| [ addressLine1 :'addressLine1', postalCode:'110111',city :[name:'Bogotá',state:'DC',country:'CO']]
    }

And my controller save methods is

@Transactional
    def save() {
        if(handleReadOnly()) {
            return
        }
        def customer = createResource()
        customer.merchant = MerchantUser.findByUsername(springSecurityService.getPrincipal().username)?.merchant
        customer.validate()
        if (customer.hasErrors()) {
            respond customer.errors, [status: UNPROCESSABLE_ENTITY] // STATUS CODE 422
            return
        }

        customer.save()

        request.withFormat {
            json {
                respond customer, [status: CREATED] // STATUS CODE 201
            }
        }
    }

If I debug the CustomerController, I found the customer resources is created with a valid Address form the send information, in fact if I run the code it works, but when running the test, the controller.response.json does not contains the address object.

I also had setup the Mock annotation for Customer and Address.

The problem can also be related to the use of custom marshallers in Unit Tests. The controller.response.json is as follows

{
    "middleName": "de",
    "id": 1,
    "lastName": "patiño",
    "phoneNumber": "20055555",
    "merchant": {
        "id": 1,
        "class": "models.Merchant"
    },
    "email": "[email protected]",
    "address": {
        "id": null,
        "class": "models.Address"
    },
    "customerToken": "21jtdik0m99pnarth8g25meb423fmoh0",
    "lastUpdated": null,
    "gender": "M",
    "dateCreated": null,
    "class": "models.Customer",
    "firstName": "bob"
}

Upvotes: 2

Views: 1953

Answers (1)

Andrew
Andrew

Reputation: 2249

I suspect that you're registering your custom JSON marshaller(s) in BootStrap.groovy, which is not executed for certain types of tests (the precise rules are unclear to me and not well documented)

One way to avoid this limitation is to use the ObjectMarshallerRegisterer approach described here: http://mrhaki.blogspot.com/2013/11/grails-goodness-register-custom.html

Upvotes: 1

Related Questions