Groovy / Grails字符串中“ \”转义字符的扩散

时间:2018-09-28 09:27:22

标签: testing grails groovy

这是一个很奇怪的问题。我正在集成测试Grails服务和关联的域类。该域类的一个属性是String,其中包含JSON。数据库字段也是json,并且有一个自定义的Hibernate值类型可以执行必要的转换。它已经在另一个领域类的生产环境中工作了多年。

class MyDomain {
    String data
    static mapping = {
        data type: StringJsonUserType
    }
}

到目前为止,一切都很好。在我的测试中,我模拟了服务方法的输入对象,该对象最终将包含并返回所需的JSON字符串。

private MockedClass mockClass() {
    // JsonRepresentable declares asJson() method.
    def data = GroovyMock(JsonRepresentable)
    data.asJson() >> "{\"content\":\"irrelevant\"}"

    def mockClass = GroovyMock(MockedClass)
    mockClass.getData() >> data

    return mockClass
}

服务方法(简体):

void persist(MockedClass mock) {
    String string = mock.data.asJson()
    def domain = new MyDomain(data: mock.data.asJson())
    domain.save()
}

当我使用调试器进入此代码时,我可以立即看到字符串已从{"content":"irrelevant"}变量中的string变为"{\"content\":\"irrelevant\"}"变量中的domain

这只是合乎逻辑的,在我的测试中,已保存的域类字符串的比较与模拟的输入不匹配。

这是从数据库读取MyDomain.data数据时的样子:

"\"\\\"{\\\\\\\"content\\\\\\\":\\\\\\\"irrelevant\\\\\\\"}\\\"\""

这与用new JsonSlurper().parseText(MyDomain.data)解析的字符串相同:

"\"{\\\"content\\\":\\\"irrelevant\\\"}\""

这是用JsonSlurper(如上)解析的模拟字符串:

[content:irrelevant]

很明显,最后一个例子是我所期望的。谁能告诉我为什么Groovy / Grails向我的简单且正确转义的字符串中添加了一大堆cr脚的\\吗?我什至可以尝试使用Groovy字符串'{"content":"irrelevant"}',但这没有什么区别。

1 个答案:

答案 0 :(得分:1)

只是偶然(寻找重新命名程序包后出现的其他一些奇怪的问题),我才发现造成问题的原因。在我的域类中,我不仅具有String属性,而且还具有瞬态getter和setter,它们从该字符串返回JSON对象或接受JSON对象并将其转换为字符串。

class MyDomain {
    String data
    static mapping = {
        data type: StringJsonUserType
    }

    static transients = ['dataJson']

    def getDataJson() {
        return new JsonSlurper().parseText(data)
    }

    void setDataJson(def data) {
        data = JsonOutput.toJson(data)
    }
}

很遗憾,我在setDataJson中有一个错字。它的名称为setData,因此在服务方法中用作我的String的设置器。

void persist(MockedClass mock) {
    String string = mock.data.asJson()
    def domain = new MyDomain(data: mock.data.asJson())
    domain.save()
}

这意味着JsonOutput.toJson(data)将我的JSON字符串转换为另一个JSON字符串,这就是所有其他转义字符的来源。

故事的寓言:切换到在编译时强制使用类型系统的正确编译的语言。