1

Is there a way to get the application URL in a Grails integration test?

The URL should include:

  • server name
  • port
  • contextPath

e.g. "localhost:8080/appname"

I don't mind if the protocol is included or not.

I am looking for a way to do this at runtime - hardcoding the URL into e.g. Config.groovy is not useful.

Armand
  • 23,463
  • 20
  • 90
  • 119

4 Answers4

2

Here's an ugly way of doing it.

First, inject the grailsLinkGenerator bean into the integration test:

def grailsLinkGenerator

Then, construct the server URL yourself:

grailsLinkGenerator.serverBaseURL + ':' + 
        (System.properties['server.port']?:'8080') +
        grailsLinkGenerator.contextPath
Armand
  • 23,463
  • 20
  • 90
  • 119
1

test environment is not added in the config file, just add test environment and put server url there like

environments {
  development {
    grails.logging.jul.usebridge = true
    grails.serverURL = "http://test2mkb.co.in"
  }
  production {
    grails.logging.jul.usebridge = false
    grails.serverURL = "http://test2mkb.co.in"
  }
  test {
    grails.serverURL = "http://test2mkb.co.in"
  }
}

and then in test

def grailsApplication
...
String serverURL = grailsApplication.config.grails.serverURL

EDIT.........................................................................

import org.codehaus.groovy.grails.web.mapping.LinkGenerator
...
LinkGenerator grailsLinkGenerator
...
String serverURL = grailsLinkGenerator.serverBaseURL

Try this..,.

MKB
  • 7,587
  • 9
  • 45
  • 71
  • Great, thanks - but how does it know the server port and context path? – Armand Oct 09 '13 at 11:18
  • `grails.serverURL` is server url in my case `http://test2mkb.co.in` is my sample app url. In your case `http://localhost:8080/appname`. And `grailsApplication.config.grails.serverURL` gives you `http://localhost:8080/appname` – MKB Oct 09 '13 at 11:25
  • I've edited the question to make it clear that I want to get these values at runtime rather than hardcoding them. Sorry for the confusion. – Armand Oct 09 '13 at 11:40
  • ...although the LinkGenerator is not initialised. Perhaps it's a Spring bean? – Armand Oct 09 '13 at 11:49
0

the same as above but metion the port explicitily

environments {
  development {
    grails.logging.jul.usebridge = true
    grails.serverURL = "http://test2mkb.co.in:8080/"
  }
  production {
    grails.logging.jul.usebridge = false
    grails.serverURL = "http://test2mkb.co.in:8080/"
  }
  test {
    grails.serverURL = "http://test2mkb.co.in:8080/"
  }
}

on buildconfig.groovy

grails.server.port.http="8080" 

The run your app as grails -Dgrails.env=test test-app To run the server in any port of your choice like 8188 ,8181

grails -Dgrails.port = 8181 test-app

Community
  • 1
  • 1
Develop4Life
  • 7,581
  • 8
  • 58
  • 76
0

My take on it for Grails 3.x, based on the other answers and nicely wrapped in a trait for easy reuse:

BaseUrl.groovy

/**
 * Exposes the {@code baseUrl} property for integration and functional tests, i.e. {@code http://<host>:<port><contextPath><path>}, where
 * {@code path} is optionally provided by implementing classes by overriding the {@link #getPath()} method.<br><br>
 * 
 * <b>Please note</b> that this trait requires {@code grailsApplication} to be present on the implementing class. This may be achieved
 * by annotating the test class with {@code @TestFor(...)}.
 * 
 * @author Michael Jess (http://stackoverflow.com/users/1821301/michael-jess)
 *
 */
trait BaseUrl {

    /**
     * Retrieves the grails link generator
     * 
     * @return the {@code grailsLinkGenerator} bean
     */
    private def getGrailsLinkGenerator() {
        assert grailsApplication, "grailsApplication not set, did you forget the @TestFor annotation?"
        grailsApplication.mainContext.getBean("grailsLinkGenerator")
    }

    /**
     * Returns the server base URL as provided by the link generator
     * 
     * @return The server base url ({@code http://<host>:<port>})
     */
    private def getServerBaseUrl() {
        getGrailsLinkGenerator().serverBaseURL
    }

    /**
     * Returns the context path as provided by the link generator
     * 
     * @return The context path (e.g. {@code /<appName>} pre-grails 3.x)
     */
    private def getContextPath() {
        getGrailsLinkGenerator().contextPath
    }

    /**
     * Returns the grails application base URL
     * 
     * @return The grails application base URL ({@code http://<host>:<port><contextPath><path>})
     */
    def getBaseUrl() {
        getServerBaseUrl() + getContextPath() + getPath()
    }

    /**
     * Returns the path of the current controller under test. Should be overridden by test classes.
     * 
     * @return The controller path fragment
     */
    def getPath() { "" }

}

Just implement it like so:

@TestFor(MyController)
class MyControllerSpec extends Specification implements BaseUrl {

    @Override
    def getPath() { "/api/myController" }
    ...

And then in the test cases:

...
get("$baseUrl/you/name/it")
...
Michael Jess
  • 1,907
  • 1
  • 19
  • 17