With just simple following controller action spock integration-test. Here is my Test.
@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
}
}
getting following Exception
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)
Unfortunately it might be a limitation in Grails 3, that you cannot use integration tests to test controllers.
Source from Grails documentation
This seems to be a major change of direction from previous versions of grails. If you really need to test a controller in an integration test, you could try doing this:
NOTE: I realize this might be a bad practice, and it goes against Grails documentation, but sometimes you also need to test things more programmatically, where unit tests aren't sufficient, and are Geb tests aren't granular enough.
WARNING: After some additional work with this format I did find a problem. Using
@TestFor
will callHolders.clear()
when it is complete, which means that there will not be agrailsApplication
object inHolders
. This will cause problems if you have any integration tests that run after one that uses the approach above. After much digging, it doesn't look like there is an easy (or even hard) way of making this work, which is possibly why it is not supported in Grails 3. That being said, one option is to mark other integration tests with@TestFor
, so that theHolders
class will be properly populated. Is this a hack? Yes it is! You will need to decide if it is worth the effort of adding this overhead to all tests. In my case it was only one other integration test that needed this (as it is a small application), but if it was more than that I would not use this approach.I've been doing this and it seems to work fine:
Add field:
In
setup()
:GrailsWebMockUtil.bindMockWebRequest(ctx)
In
cleanup()
:RequestContextHolder.resetRequestAttributes()