Grails 3:单元测试拦截器:不会在拦截器中停止

时间:2019-02-05 15:35:21

标签: java unit-testing grails grails-3.0 grails-3.3.x

出于演示目的,我使用以下文件设置了一个全新的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()。如何在测试中获得模型?

3 个答案:

答案 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方法在   拦截器执行的上下文。通常完成此操作以调用依赖于拦截器行为的控制器操作

https://testing.grails.org/latest/guide/index.html

答案 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"
    }
}