如何在grails 2.4.3中的控制器中测试复合json对象响应

时间:2014-11-05 00:03:39

标签: rest grails testing junit spock

我正在测试Restful控制器的保存方法CustomerController

客户(域类)具有地址关联,地址具有城市,城市具有州,州具有国家/地区。

我为Address编写了自定义封送程序和自定义绑定帮助程序,因此JSON客户是这样的:

{
    "id": "g2c3e08iqton4v5bsgti33gkpd35l0er",
    "firstName": "Bob1",
    "lastName": "Patiño1",
    "middleName": "The Payaso1",
    "email": "me@bobpatino.org",
    "phoneNumber": "300555551",
    "address": {
        "addressLine1": "addressLine1",
        "postalCode": "110111",
        "city": {
            "name": "Bogotá",
            "state": "DC",
            "country": "CO"
        }
    }
}

一切都在使用这种格式,记住自定义编组器和地址的绑定助手,但现在我想测试控制器。

 @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'   |'bob@patino.co'| '20055555'| [ addressLine1 :'addressLine1', postalCode:'110111',city :[name:'Bogotá',state:'DC',country:'CO']]
    }

我的控制器保存方法是

@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
            }
        }
    }

如果我调试CustomerController,我发现客户资源是用发送信息的有效地址创建的,实际上如果我运行它运行的代码,但是在运行测试时, controller.response.json 不包含地址对象。

我还为客户和地址设置了Mock注释。

问题还可能与在单元测试中使用自定义编组器有关。 controller.response.json如下

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

1 个答案:

答案 0 :(得分:1)

我怀疑您在BootStrap.groovy中注册了自定义JSON编组程序,而这些编组程序并未针对某些类型的测试执行(准确的规则对我来说并不清楚,并且没有详细记录)

避免此限制的一种方法是使用此处所述的ObjectMarshallerRegisterer方法:http://mrhaki.blogspot.com/2013/11/grails-goodness-register-custom.html