Grails 3:单元测试拦截器:不会在拦截器中停止
Posted
技术标签:
【中文标题】Grails 3:单元测试拦截器:不会在拦截器中停止【英文标题】:Grails 3: Unit Testing Interceptors: Doesn't halt in interceptor 【发布时间】:2019-06-29 11:29:50 【问题描述】:出于演示目的,我使用这些文件设置了一个全新的 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
。如何在我的测试中获取模型?
【问题讨论】:
【参考方案1】:如果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
【讨论】:
【参考方案2】:对我来说,诀窍是自己调用拦截器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"
【讨论】:
【参考方案3】:您需要使用 withInterceptors
方法而不是 withRequest
- withRequest 仅验证匹配与否 - 因此拦截器从未实际运行。
来自文档:
withInterceptors:
您可以使用 withInterceptors 方法在 拦截器执行的上下文。这通常用于调用依赖于拦截器行为的控制器操作。
https://testing.grails.org/latest/guide/index.html
【讨论】:
这对我不起作用,拦截器代码仍然没有被调用。以上是关于Grails 3:单元测试拦截器:不会在拦截器中停止的主要内容,如果未能解决你的问题,请参考以下文章