Grails3控制器集成测试用例失败:未找到线程绑定请求

use*_*671 5 grails integration-testing grails-plugin grails-3.0

只需简单的跟随控制器动作spock集成测试.这是我的测试.

@Integration
@Rollback
class TestControllerSpec extends Specification {

    def setup() {
    }

    def cleanup() {
    }

    void "test something"() {
       setup:
        def c = new TestController()
        c.index()
        expect:
        c.response.contentType !=null
    }
}
Run Code Online (Sandbox Code Playgroud)

获得以下异常

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
    at grails.web.api.WebAttributes$Trait$Helper.currentRequestAttributes(WebAttributes.groovy:45)
    at grails.web.api.ServletAttributes$Trait$Helper.getRequest(ServletAttributes.groovy:42)
Run Code Online (Sandbox Code Playgroud)

Hyp*_*eMK 10

我一直这样做,似乎工作正常:

添加字段:

@Autowired
WebApplicationContext ctx
Run Code Online (Sandbox Code Playgroud)

setup(): GrailsWebMockUtil.bindMockWebRequest(ctx)

cleanup(): RequestContextHolder.resetRequestAttributes()


mnd*_*mnd 4

不幸的是,这可能是 Grails 3 中的一个限制,您无法使用集成测试来测试控制器。

对于集成测试控制器,建议您使用 create-function-test 命令来创建 Geb 功能测试。

来源自 Grails 文档

这似乎是与以前版本的 grails 相比的一个重大方向变化。如果您确实需要在集成测试中测试控制器,您可以尝试这样做:

注意:我意识到这可能是一种不好的做法,并且它违背了 Grails 文档,但有时您还需要以编程方式进行更多测试,其中单元测试不够充分,并且 Geb 测试不够精细。

@TestFor(TestController) // This will provide a mocked "controller" reference
@Integration
@Rollback
class TestControllerSpec extends Specification {

    // If TestController uses any services, have them autowired into this test
    @Autowired
    SomeService someService

    def setupSpec() {
        // Now connect those services to the controller
        controller.someService = someService
    }

    void "test something"() {
        when:
        controller.index()

        then:
        response.contentType != null
    }
}
Run Code Online (Sandbox Code Playgroud)

警告:在对这种格式进行一些额外的工作后,我确实发现了一个问题。using完成后@TestFor会调用,这意味着. 如果您有任何集成测试在使用上述方法的测试之后运行,这将导致问题。经过大量挖掘后,似乎没有一种简单(甚至困难)的方法可以完成这项工作,这可能就是 Grails 3 不支持它的原因。话虽这么说,一种选择是将其他集成测试标记为,以便正确填充该类。这是黑客攻击吗?是的!您需要决定是否值得将这种开销添加到所有测试中。就我而言,只有另一个集成测试需要这种方法(因为它是一个小型应用程序),但如果超过这个要求,我就不会使用这种方法。Holders.clear()grailsApplicationHolders@TestForHolders