如何在grails测试中比较JSON

时间:2013-09-20 12:52:59

标签: grails groovy

我在Grails中有一个控制器,它在JSON中返回一个响应。

我写了一个大致类似的测试

test(){
     def expectedResponse=JSON.parse('[{"username":"user","startDate":"2010-11-30"}]')
    ...
            def actualResponse=JSON.parse(response.text)

            println "Expecting: ${expectedResponse.toString()}"
            println "Actual: ${actualResponse.toString()}"

            assertEquals(expectedResponse.toString(), actualResponse.toString())
    ...
        }

这可以按预期工作

Expecting: [{"username":"user","startDate":"2010-11-30"}]
Actual: [{"username":"user","startDate":"2010-11-30"}]

但是,我想知道是否有一种更好的方法可以在不使用字符串比较的情况下执行此操作。或许可以让我灵活地在响应中添加属性而不会使我的测试用例无效?

我可以自己构建,但我希望将某种JSON比较内置到该语言中。

更新: 我尝试直接这样做,没有toString并且有不一致的结果,不太确定为什么,它在一个阶段工作然后突然得到了这个。我无法看到我所做的任何代码更改会导致差异

groovy.lang.MissingMethodException: No signature of method: com.siggysale.MainControllerTests.assertEquals() is applicable for argument types: (org.codehaus.groovy.grails.web.json.JSONArray, org.codehaus.groovy.grails.web.json.JSONArray) values: [[], []]

3 个答案:

答案 0 :(得分:5)

您可以使用以下代码使用GJSON libraray比较json。

class GJsonUtil {

    static Boolean compareJsonStrings(String obj1, String obj2){
        JsonParser parser = new JsonParser();
        JsonElement o1 = parser.parse(obj1)
        JsonElement o2 = parser.parse(obj2)
        return o1==o2
    }
}

这也是使用少量测试用例进行测试的。正如你所看到的,json中元素的顺序无关紧要,即{test1:1,test2:2}应该与{test2:2,test1:1}相同。

class GJsonSpec extends UnitSpec {

    @Unroll("#ID : comparing two json")
    def "Comparing json string"() {

        setup:

        when:
        def json1String = (obj1 as JSON).toString()
        def json2String = (obj2 as JSON).toString()
        println "json1String=${json1String}"
        println "json2String=${json2String}"
        def match=GJsonUtil.compareJsonStrings(json1String,json2String)

        then:
             match==result

        where:

        ID | obj1                    | obj2                    | result
        1  | [a: 1, b: [c: 1, d: 2]] | [b: [c: 1, d: 2], a: 1] | true
        2  | [a: 1, b: [c: 1, d: 3]] | [b: [c: 1, d: 2], a: 1] | false
        3  | [a: 2, b: [c: 1, d: 2]] | [b: [c: 1, d: 2], a: 1] | false
        4  | [a: 1, b: [d: 1, c: 2]] | [b: [d: 1, c: 2], a: 1] | true
        5  | [a: 1, b: [d: [x:"ram",y:"Laxman"], c: 2]] | [b: [d: [x:"ram",y:"Laxman"], c: 2], a: 1] | true//deep json comparision
        6  | [a: 1, b: [d: [x:"Ram",y:"Laxman"], c: 2]] | [b: [d: [x:"ram",y:"laxman"], c: 2], a: 1] | false//deep json comparision+ lower/uppercase
        7  | [a: 1, b: [d: [x:"Ram",y:["test1","test2","test3"]], c: 2]] | [b: [d: [x:"Ram",y:["test1","test3","test2"]], c: 2], a: 1] | false//deep json comparision+ lower/uppercase
        8  | [a: ["test1","test2","test3"]] | [a:["test1","test2","test3"] ] | true//comaparing list order
        9  | [a: ["test1","test2","test3"]] | [a:["test1","test3","test2"] ] | false//comaparing list order should fail
        10|[:]|null|false
        11|null|[:]|false
        12|null|null|true
        13|[a: ["test1",null,"test3"]] | [a:["test1",null,"test3"] ] | true//comaparing nulls in json



    }


}

希望有所帮助!!! 谢谢,

Anuj Aneja

答案 1 :(得分:1)

如何比较JSON值?

import groovy.json.JsonSlurper

def test() {
    def obj = new JsonSlurper().parseText(response.text)

    assert obj[0].username == "user"
    assert obj[0].startDate == "2010-11-30"

    // make sure there isn't any other data
    assert obj.size() == 1
    assert obj[0].size() == 2
}

(您必须使用obj[0]而不是obj,因为您返回的是带有1个元素的JSON数组)

答案 2 :(得分:0)

I use org.skyscreamer.jsonassert.JSONAssert. Is at simple as:

JSONAssert.assertEquals(expectedJson, json, true)