[英]Grails 3: Unit Testing Interceptors: Doesn't halt in interceptor
出于演示目的,我使用这些文件设置了一个新的 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()
方法中设置了一个断点,在调试测试时我从未到达那里。 这很奇怪,因为我希望拦截器测试至少会调用拦截器。 我知道我可以按照这里的描述重写测试,但我的观点是拦截器根本不会被调用。 那正确吗? 另一件事:在测试中调用getModel()
总是返回null
。 我如何在我的测试中获得模型?
我的诀窍是自己调用拦截器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"
}
}
如果这对withInterceptors
仍然存在,则可能是因为https://github.com/grails/grails-testing-support/issues/29
一种解决方法是在真正的“加载拦截器测试”之前添加一个假的“加载拦截器测试”:
void "Fake test to load interceptor"() {
// this is necessary because of this: https://github.com/grails/grails-testing-support/issues/29
given:
def controller = (PostController) mockController(PostController)
when:
withInterceptors(controller: 'post') { true }
then:
true
}
您需要使用withInterceptors
方法而不是withRequest
- withRequest 只验证匹配与否 - 所以拦截器实际上从未运行过。
从文档:
带拦截器:
您可以使用 withInterceptors 方法在拦截器执行的上下文中执行代码。 这通常用于调用依赖于拦截器行为的控制器操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.