【问题标题】:Grails - How to instantiate service in Controller when doing controller testingGrails - 进行控制器测试时如何在控制器中实例化服务
【发布时间】:2025-11-25 11:20:12
【问题描述】:

我在控制器中使用服务。我正在为控制器编写单元测试,但我无法在控制器中实例化服务。总是null

如果我在 Controller 测试类中使用 new 运算符实例化服务。服务类中的服务未实例化。

如何在测试类中实例化服务?

【问题讨论】:

    标签: grails grails-controller


    【解决方案1】:

    你可以让 Spring 为你做这件事。

    依赖于服务的控制器:

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

    服务:

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

    注入服务的单元测试:

    // 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'
        }
    }
    

    注入虚假版本服务的单元测试:

    // 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
        }
    }
    

    【讨论】:

    • 如果你注入的服务依赖于其他 bean,也可以在 doWithSpring 中安装。
    • 我仍然收到null 用于服务中注入的 bean。
    • 给我一分钟。我会上传一个例子。
    • 查看项目github.com/jeffbrown/serviceinjectiongithub.com/jeffbrown/serviceinjection/commit/… 的提交演示了一种安装依赖于另一个服务的服务的方法。
    • 您可以在doWithSpring 块中配置任意数量的bean。 Spring 将自动连接您的依赖关系树任意深度,但在单元测试中,几乎不需要安装超过 2 级的依赖关系。您不必为单元测试构建一个巨大的对象图,但您可以。
    最近更新 更多