我有一个场景,我想在功能测试期间覆盖某些控制器,以便在运行时调用模拟控制器。我可以像这样轻松覆盖resources.groovy中的服务:(记录here和here。)
// 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
}
}
答案 0 :(得分:2)
由于它们不是可自动装配的,因此控制器在spring上下文中的bean名称下注册,该bean名称与其完全限定的类名称匹配,而不是服务使用的“属性名称”表示。因此,您需要将测试bean注册为com.example.ExpensiveToUseController
而不是expensiveToUseController
。
但是将环境检查放在控制器本身的“昂贵”操作中可能更容易。我认为实例化控制器的行为不能太昂贵,因为默认情况下控制器是原型范围。