Search code examples
grailsgrails-controller

Grails - How to instantiate service in Controller when doing controller testing


I am using a service in controller. I am writing unit test for the controller but I am unable to instantiate service in controller. It is always null.

if I instantiate service using new operator in Controller testing class. The services in the service class are not instantiated.

How can I instantiate a service in testing class?


Solution

  • You can let Spring do it for you.

    A controller that depends on a service:

    // grails-app/controllers/demo/DemoController.groovy
    package demo
    
    class DemoController {
        def helperService
    
        def index() {
            def answer = helperService.theAnswer
            render "The answer is ${answer}"
        }
    }
    

    The service:

    // grails-app/services/demo/HelperService.groovy
    package demo
    
    class HelperService {
    
        def getTheAnswer() {
            42
        }
    }
    

    A unit test which injects the service:

    // src/test/groovy/demo/DemoControllerSpec.groovy
    package demo
    
    import grails.test.mixin.TestFor
    import spock.lang.Specification
    
    @TestFor(DemoController)
    class DemoControllerSpec extends Specification {
    
        static doWithSpring = {
            helperService HelperService
        }
    
        void "test service injection"() {
            when:
            controller.index()
    
            then:
            response.text == 'The answer is 42'
        }
    }
    

    A unit test which injects a fake version of the service:

    // src/test/groovy/demo/AnotherDemoControllerSpec.groovy
    package demo
    
    import grails.test.mixin.TestFor
    import spock.lang.Specification
    
    @TestFor(DemoController)
    class AnotherDemoControllerSpec extends Specification {
    
        static doWithSpring = {
            helperService DummyHelper
        }
    
        void "test service injection"() {
            when:
            controller.index()
    
            then:
            response.text == 'The answer is 2112'
        }
    }
    
    class DummyHelper {
    
        def getTheAnswer() {
            2112
        }
    }