0

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

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

1 回答 1

2

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

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

于 2013-03-29T11:49:34.363 回答