出于演示目的,我使用以下文件设置了一个全新的grails应用程序:
const redis = require('redis');
const config = {
host: '127.0.0.1',
port: '6666',
password: 'mypassword'
};
const redisClient = redis.createClient(config);
class HalloController {
def index() {
String heading = request.getAttribute("heading")
render "${heading}"
}
}
当我进入http://localhost:8080/hallo时,因为在拦截器class HalloInterceptor {
boolean before() {
request.setAttribute("heading", "halloechen") // *** set breakpoint here***
true
}
boolean after() { true }
void afterView() {
// no-op
}
}
方法中将其设置为请求属性,所以打印出“ 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
方法中设置了一个断点,并且在调试测试时我从未到达过。这很奇怪,因为我希望拦截器测试至少可以调用拦截器。
我知道我可以按照here所述重写测试,但是我的意思是,拦截器根本不会被调用。
那正确吗?另一件事:在测试中始终调用before()
会返回getModel()
。如何在测试中获得模型?
答案 0 :(得分: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
}
答案 1 :(得分:0)
您需要使用withInterceptors
而不是withRequest
的方法-withRequest只验证匹配还是不验证-这样拦截器就不会真正运行。
从文档中
withInterceptors:
您可以使用withInterceptors方法在 拦截器执行的上下文。通常完成此操作以调用依赖于拦截器行为的控制器操作。
答案 2 :(得分:0)
对我来说,技巧就是自己调用拦截器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"
}
}