繁体   English   中英

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

[英]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 方法在拦截器执行的上下文中执行代码。 这通常用于调用依赖于拦截器行为的控制器操作

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM