Grails Goodness: Use Random Server Port In Integration Tests
Because Grails 3 is based on Spring Boot we can use a lot of the functionality of Spring Boot in our Grails applications.
For example we can start Grails 3 with a random available port number, which is useful in integration testing scenario's.
To use a random port we must set the application property server.port
to the value 0
.
If we want to use the random port number in our code we can access it via the @Value
annotation with the expression ${local.server.port}
.
Let's create a very simple controller with a corresponding integration test.
The controller is called Sample
:
// File: grails-app/controllers/mrhaki/SampleController.groovy
package mrhaki
class SampleController {
def index() {
respond([message: 'Grails 3 is awesome!'])
}
}
We write a Spock integration test that will start Grails and we use the HTTP Requests library to access the /sample
endpoint of our application.
// File: src/integration-test/groovy/mrhaki/SampleControllerIntSpec.groovy
package mrhaki
import com.budjb.httprequests.HttpClient
import com.budjb.httprequests.HttpClientFactory
import grails.test.mixin.integration.Integration
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import spock.lang.Specification
@Integration
class SampleControllerIntSpec extends Specification {
/**
* Server port configuration for Grails test
* environment is set to server.port = 0, which
* means a random available port is used each time
* the application starts.
* The value for the port number is accessible
* via ${local.server.port} in our integration test.
*/
@Value('${local.server.port}')
Integer serverPort
/**
* HTTP test client from the HTTP Requests library:
* https://ift.tt/27dKa7E
*/
@Autowired
HttpClientFactory httpClientFactory
private HttpClient client
def setup() {
// Create HTTP client for testing controller.
client = httpClientFactory.createHttpClient()
}
void "sample should return JSON response"() {
when:
// Nice DSL to build a request.
def response = client.get {
// Here we use the serverPort variable.
uri = "http://localhost:${serverPort}/sample"
accept = 'application/json'
}
then:
response.status == 200
and:
final Map responseData = response.getEntity(Map)
responseData.message == 'Grails 3 is awesome!'
}
}
Finally we add the server.port
to the application configuration:
# File: grails-app/conf/application.yml
...
environments:
test:
server:
port: 0 # Random available port
...
Let's run the integration test: $ grails test-app mrhaki.SampleControllerIntSpec -integration
.
When we open the test report and look at the standard output we can see that a random port is used:
Written with Grails 3.1.6.