为了演示我已经设置了这些文件的一个新的Grails应用程序:
class HalloController {
def index() {
String heading = request.getAttribute("heading")
render "${heading}"
}
}
class HalloInterceptor {
boolean before() {
request.setAttribute("heading", "halloechen") // *** set breakpoint here***
true
}
boolean after() { true }
void afterView() {
// no-op
}
}
当我到http://localhost:8080/hallo“halloechen”会打印,因为这被设置为拦截before()
方法的请求属性,就像我希望它是。现在我想为拦截一个单元测试:
class HalloInterceptorSpec extends Specification implements InterceptorUnitTest<HalloInterceptor> {
def setup() {
}
def cleanup() {
}
void "Test hallo interceptor matching"() {
when:"A request matches the interceptor"
withRequest(controller:"hallo")
then:"The interceptor does match"
interceptor.doesMatch() && request.getAttribute("heading") == "halloechen"
}
}
作为heading
属性不被设置为请求(这是反正嘲笑请求)这个测试失败。事实上,在运行单元测试时,它似乎拦截器甚至不被调用。我已在before()
方法中设置断点和调试测试时,我从来没有在那里。这是奇怪的,因为我希望一个拦截试验至少调用拦截。我知道我可以重写测试描述here但我的观点是,拦截没有得到根本调用。那正确吗?另一件事:调用getModel()
测试送花儿给人返回null
。我如何在我的测试模型?
您需要使用的,而不是withInterceptors
的withRequest
方法 - withRequest只验证匹配与否 - 所以拦截器从未居然跑。
从文档:
withInterceptors:
您可以使用withInterceptors方法来执行拦截的上下文中执行代码。这通常是调用依赖于从拦截行为控制器动作。
对我来说,诀窍是调用拦截before()
方法自己:
import grails.testing.web.interceptor.InterceptorUnitTest
import spock.lang.Specification
class HalloInterceptorSpec extends Specification implements InterceptorUnitTest<HalloInterceptor> {
def setup() {
}
def cleanup() {
}
void "Test hallo interceptor matching"() {
when: "A request matches the interceptor"
withRequest(controller: "hallo")
interceptor.before()
then: "The interceptor does match"
interceptor.doesMatch() && request.getAttribute("heading") == "halloechen"
}
}