如何在grails测试中比较JSON

Sam*_*age 3 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())
    ...
        }
Run Code Online (Sandbox Code Playgroud)

这按预期工作

Expecting: [{"username":"user","startDate":"2010-11-30"}]
Actual: [{"username":"user","startDate":"2010-11-30"}]
Run Code Online (Sandbox Code Playgroud)

但是,我想知道是否有更好的方法来做这个而不采用字符串比较.也许某些东西可以让我灵活地能够在不使我的测试用例无效的情况下为响应添加属性?

我可以自己构建这个,但我希望将某种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: [[], []]
Run Code Online (Sandbox Code Playgroud)

Anu*_*eja 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
    }
}
Run Code Online (Sandbox Code Playgroud)

这也是使用少量测试用例进行测试的.正如你所看到的,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



    }


}
Run Code Online (Sandbox Code Playgroud)

希望有所帮助!谢谢,

Anuj Aneja