在Grails 2.1.1应用程序中,我正在尝试对使用的控制器进行单元测试 'withFormat'以HTML或JSON格式呈现响应。但是,响应HTML内容类型始终会导致 我的测试中的空响应,除非我将其包装在闭包中并显式调用'render'。对于JSON, 它会发回预期的响应。
控制器:
import grails.converters.JSON
class TestController {
def formatWithHtmlOrJson() {
withFormat {
html someContent:"should be HTML"
json {render new Expando(someContent:"should be JSON") as JSON}
}
}
测试:
@TestFor(TestController)
class TestControllerTests {
void testForJson() {
response.format = "json"
controller.formatWithHtmlOrJson()
println("resp: $response.contentAsString")
assert response.json.properties.someContent == "should be JSON"
}
void testForHtml() {
response.format = "html"
controller.formatWithHtmlOrJson()
println("resp: $response.contentAsString")
// fails here, response is empty
assert response.text
//never gets this far
assert response.contentAsString.contains("HTML")
}
}
如上所述,对于JSON,这是有效的,但对于HTML,我总是得到一个空的 响应,除非我将html检查包装在一个闭包中并显式调用render,如下所示:
withFormat {
html {
render someContent:"should be HTML"
}
文档建议我不应该这样做,例如:
withFormat {
html bookList: books
js { render "alert('hello')" }
xml { render books as XML }
}
来自http://grails.org/doc/2.2.x/ref/Controllers/withFormat.html
令人沮丧的是,关于测试的grails文档提到了使用withFormat,但仅提供了测试xml / json的示例,而没有为html响应提供任何内容。
http://grails.org/doc/latest/guide/testing.html#unitTestingControllers
任何人都可以解释这种差异,或者我如何解决这个问题 测试
答案 0 :(得分:3)
终于想通了。
在文档(http://grails.org/doc/latest/guide/testing.html#unitTestingControllers)中,它提到了在测试操作返回地图下测试控制器响应的方法 :
import grails.test.mixin.*
@TestFor(SimpleController)
class SimpleControllerTests {
void testShowBookDetails() {
def model = controller.showBookDetails()
assert model.author == 'Alvin Plantinga'
}
}
同样的方法适用于使用 withFormat 的控制器方法。
所以对于我上面的原始例子:
withFormat {
html someContent:"should be HTML"
...
测试成为:
void testForHtml() {
response.format = "html"
def model = controller.formatWithHtmlOrJson()
assert model.someContent == "should be HTML"
}
由于 withFormat 部分未提及此方法,因此文档有点令人困惑。
值得注意的是,如果其他人遇到这个问题,如果html块在闭包内,则不会返回地图,而是返回map条目的值,因此对于控制器代码:
withFormat{
html{
someContent:"should be HTML"
}...
测试检查变为:
assert model == "should be HTML"
或者,如果您可以修改控制器代码,则将结果返回到地图中可让您使用点表示法来检查元素值。对于此代码:
withFormat {
html {
[someContent:"should be HTML"]
}....
测试检查是:
assert model.someContent == "should be HTML"
另外值得注意的是,在我的原始示例中不使用HTML类型的闭包,不能将值作为地图返回 - 结果在编译错误中。
//Don't do this, won't compile
withFormat {
html [someContent:"should be HTML"]
...
答案 1 :(得分:0)
试
withFormat {
html {
println("html")
[new Expando(test:"html")]
}
}
答案 2 :(得分:0)
文档中提供的建议不使用closure
并且有这个措辞“ Grails搜索名为grails-app / views / book / list.html.gsp的视图,如果找不到回退到grails-app / views / book / list.gsp “。
当您使用closure
html
时,我们必须将model
返回到操作或render
内容。由于在这种情况下您使用html
closure
,因此必须呈现内容。
使用Closure(您的用例已通过)
withFormat{
html {
test: "HTML Content" //This will not render any content
render(test: "HTML Content") //This has to be used
}
}