Using service beans and dependency Injection in Geb Functional Tests

747 views Asked by At

I would like to use a service inside my Geb test to populate some sample data. The sample data is large and complex, and we have already written the code to create it for other controllers and services. Thus a simple mock is out of the question. How can I access this service inside of my Geb test?

Let's assume the name of my Service is testDataService, and looks something like this...

class TestDataService {

    def otherService

    void importData() {
        otherService.getData()
    }
}

Something like the following in Geb would be ideal...

class testSpec extends GebReportingSpec {

    @Shared def testDataService

    def setupSpec() {
        testDataService.importData()
    }

    def test1() {
        ...some test...
    }
}

From what I understand, this should work for a normal integration test. Since it is a functional test, things are quite different and it returns null.

I found a lot of suggestions for the Grails Remote Control plugin, but I would like to know how to do this without it.

A few side notes...

The service class is located inside src/groovy. Though I am sure I wired it in properly as it works as expected when called by other services. Only in functional tests does it not work.

Grails Version: 2.4.5

Geb 0.10.0

2

There are 2 answers

0
Jim Chertkov On BEST ANSWER

For Grails 2.4.5

def testDataService = Holders.applicationContext.getBean("testDataService")

So our testing spec could look like this...

class testSpec extends GebReportingSpec {

    @Shared def testDataService = Holders.applicationContext.getBean("testDataService")

    def setupSpec() {
        testDataService.importData()
    }

    def test1() {
        ...some test...
    }
}

Note that all injected dependencies from other services should be present.

1
cfrick On

there is the remote-control plugin: http://grails.org/plugin/remote-control; instructions are on https://github.com/alkemist/grails-remote-control/

you would add a RemoteControl instance in your test and run remote.call{ /* server side code */ } in your test (note this must return something serializeable).

in functional tests in grails you basically no longer take part in all the IoC and grails magic; you get treated like a regular client, that interacts with the server.