【问题标题】:How to override controllers in resources.groovy depending on environment?如何根据环境覆盖 resources.groovy 中的控制器?
【发布时间】:2013-03-29 10:42:16
【问题描述】:

我有一个场景,我想在功能测试期间覆盖某些控制器,以便在运行时调用模拟控制器。我可以像这样轻松地覆盖 resources.groovy 中的服务:(记录在 herehere。)

 // grails-app/conf/spring/resources.groovy
beans = {
    switch(Environment.current) {
        case Environment.TEST:
            expensiveToUseService(MockExpensiveToUseService)

            break
    }
}

当应用在测试环境中运行时,这种方法会正确重定向到模拟服务。

但是,与控制器一起使用的相同方法不起作用。这是我目前的尝试:

// grails-app/conf/spring/resources.groovy
beans = {
    switch(Environment.current) {
        case Environment.TEST:
            expensiveToUseController(MockExpensiveToUseController)

            break
    }
}

模拟控制器与原始控制器位于同一目录/包中,在 grails-app/controllers 下。

我能看到的唯一明显区别是我的服务在代码中被使用它们的控制器显式引用,例如

class ExpensiveToUseController { 
    def expensiveToUseService
...
}

另一方面,控制器仅被 Grails 运行时引用。

值得一提的是,我没有将现有控制器中的逻辑移到服务中的选项,这将提供一种解决方法。

这里有什么我遗漏的东西,还是有其他方法可以实现?

编辑:请参阅下面的答案。

对于遇到此问题的其他人,我不需要额外的 bean.scope/autowire 参数。这是我的 DSL:

beans = {
switch(Environment.current) {
    case Environment.TEST:
        'com.example.ExpensiveToUseController'(com.example.MockExpensiveToUseController)

        break
    }
}

【问题讨论】:

    标签: grails


    【解决方案1】:

    由于它们不是可自动装配的,因此控制器在 spring 上下文中注册在与其完全限定的类名匹配的 bean 名称下,而不是服务使用的“属性名称”表示。因此,您需要将您的测试 bean 注册为 com.example.ExpensiveToUseController 而不是 expensiveToUseController

    但是将环境检查放在控制器本身的“昂贵”操作中可能更容易。我认为实例化控制器的行为不会太昂贵,因为默认情况下控制器是原型范围。

    【讨论】:

    • 感谢您的建议。我已经尝试过这个,现在重新尝试了,但它不起作用。我收到以下错误:“groovy.lang.MissingPropertyException: No such property: com for class: resources” 我不想将环境检查放在控制器中,我想将我的测试代码完全分开。跨度>
    • @eustachio 你必须在 beans DSL 中引用它:'com.example.ExpensiveToUseController'(MockExpensiveToUseController) { bean -> bean.scope = 'prototype' ; bean.autowire = 'byName' }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    相关资源
    最近更新 更多