Testing Groovy/Grails的扩散\&引用;字符串中的转义字符
这是一个相当奇怪的问题。我正在集成测试Grails服务和关联的域类。该域类的一个属性是包含JSON的Testing Groovy/Grails的扩散\&引用;字符串中的转义字符,testing,grails,groovy,Testing,Grails,Groovy,这是一个相当奇怪的问题。我正在集成测试Grails服务和关联的域类。该域类的一个属性是包含JSON的字符串。数据库字段也是json,并且有一个自定义的Hibernate值类型来执行必要的转换。它已经在另一个领域类的生产中工作了多年 class MyDomain { String data static mapping = { data type: StringJsonUserType } } 到目前为止还不错。在我的测试中,我将模拟一个输入对象到我的服务
字符串。数据库字段也是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
}
服务方法(简化):
当我使用调试器进入这段代码时,我可以立即看到字符串已从字符串
变量中的{“content”:“unrelated”}
变为域
变量中的“{content\”:\“unrelated\”}
现在唯一合乎逻辑的是,在我的测试中,保存的域类字符串的比较与模拟输入不匹配
这是从数据库读取数据时的MyDomain.data
data的外观:
“\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/code>
这是使用new JsonSlurper()解析的相同字符串。parseText(MyDomain.data)
:
“\”{\\\\\“内容\\”:\\\\“无关\\”}\”
下面是用JsonSlurper解析的模拟字符串(如上所述):
[内容:无关]
显然,最后一个例子就是我所期望的。有人能告诉我为什么Groovy/Grails会在我的简单且正确转义的字符串中添加大量crapy\\s吗?我甚至可以尝试使用Groovy字符串'{“content”:“uncertible”}
,但这没有任何区别。只是出于偶然(在查找重命名包后出现的一些其他奇怪问题时),我发现了问题的原因。在我的域类中,我不仅有String
属性,还有从该字符串返回JSON对象或接受JSON对象并将其转换为字符串的临时getter和setter
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
,因此它被用作服务方法中我的字符串的setter
void persist(MockedClass mock) {
String string = mock.data.asJson()
def domain = new MyDomain(data: mock.data.asJson())
domain.save()
}
这意味着JsonOutput.toJson(data)
将我的JSON字符串转换为另一个JSON字符串,这就是所有附加转义字符的来源
故事的寓意:切换到正确编译的语言,在编译时强制执行类型系统
void persist(MockedClass mock) {
String string = mock.data.asJson()
def domain = new MyDomain(data: mock.data.asJson())
domain.save()
}