【问题标题】:Grails 3: Unit Testing Interceptors: Doesn't halt in interceptorGrails 3:单元测试拦截器:不会在拦截器中停止
【发布时间】: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。如何在我的测试中获取模型?

【问题讨论】:

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


    【解决方案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

        【讨论】:

        • 这对我不起作用,拦截器代码仍然没有被调用。
        猜你喜欢
        • 2016-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-22
        • 1970-01-01
        • 2013-06-25
        • 2018-08-09
        • 1970-01-01
        相关资源
        最近更新 更多