在Grails中使用JsonBuilder渲染Json的单元测试

4
假设我在控制器中有一个简单的操作,以以下内容结束:
render(contentType: "text/json") {
    message = 'some text'
    foo = 'bar'
}

它根据JSON生成器文档正确渲染。但是,当我尝试在ControllerUnitTest中对该响应进行单元测试时,使用controller.response.contentAsString得到一个空字符串。我甚至尝试了controller.renderArgs,但那只包含contentType:"text/json"。当我将JSON转换为映射并将其编组为as JSON时,我可以正常测试。但是,是否有一种方法可以按照现有的代码进行单元测试?
3个回答

0

你必须在你的测试中调用该操作,并使用controller.response.contentAsString比较结果。

因此,你的测试方法看起来会像这样:

void testSomeRender() {
controller.someRender()
assertEquals "jsonString", controller.response.contentAsString

}

我已经尝试过这个,但是像我之前提到的那样,我只得到了一个空字符串(或者它包含"contentType: 'text/json'",我记不清了)。 - Igor
我刚刚添加了一个代码,用于返回像您正在尝试做的那样的JSON字符串,但我没有看到任何内容。因此,问题在于内容未被呈现。您使用的Grails版本是什么? - allthenutsandbolts
1.3.7,我知道2.0有更好的支持,但不幸的是我无法切换到那个版本。:-\ - Igor
1.3.7是比2.0更稳定的版本。2.3本来不应该在十月份发布,但他们已经发布了修复bug的版本。我认为JSON转换器不会将任何字符串对象转换为JSON,因此它返回空字符串。我尝试过的一件事是创建一个Expando对象并向其添加属性,然后呈现它,这样就可以解决问题。我认为你应该尝试一下。希望能有所帮助。 - allthenutsandbolts

0

损坏的链接,404。 - nasch

0

经过长时间的搜索,我发现在1.3.7版本中这是不可能实现的。你要么升级到Grails 2.0版本,要么按照this post中的建议覆盖控制器metaClass。

controller.class.metaClass.render = { Map map, Closure c ->
    renderArgs.putAll(map)

    switch(map["contentType"]) {
        case null:
            break

        case "application/xml":
        case "text/xml":
            def b = new StreamingMarkupBuilder()
            if (map["encoding"]) b.encoding = map["encoding"]

            def writable = b.bind(c)
            delegate.response.outputStream << writable
            break

        case "text/json":
            new JSonBuilder(delegate.response).json(c)
            break
        default:
            println "Nothing"
            break
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接