Spring 如何在针对服务的spock测试中模拟自动连线bean?

Spring 如何在针对服务的spock测试中模拟自动连线bean?,spring,unit-testing,grails,spock,Spring,Unit Testing,Grails,Spock,我需要将bean注入到服务中,以便测试能够工作。我有这个服务班: class ContentService { @Autowired Evaluator evaluator ... } 当运行它的单元测试对应项时,它失败了,因为它说它找不到一个与求值器bean匹配的bean。我的理解是Grails设法为您自动实例化服务变量,但这里似乎缺少一些信息来正确构建它。这就是测试: @TestFor(ContentService) class ContentService

我需要将bean注入到服务中,以便测试能够工作。我有这个服务班:

class ContentService {

    @Autowired
    Evaluator evaluator

    ... 

}
当运行它的单元测试对应项时,它失败了,因为它说它找不到一个与
求值器
bean匹配的bean。我的理解是Grails设法为您自动实例化服务变量,但这里似乎缺少一些信息来正确构建它。这就是测试:

@TestFor(ContentService)
class ContentServiceSpec extends Specification {

    def setup() {
        evaluator = Mock(Evaluator)
        service.evaluator = evaluator
    }

    def "Should test..."() {
       ...
    }

}
模仿
实验评估器
并将其手动注入
setup()
方法中的测试,似乎为时已晚,因为它失败于:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [ExperimentEvaluator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 28 more
我已经看到了一些关于
defineBeans
的引用,尽管它似乎不再在2.5.0中使用。我无法理解如何使用它,因为Grails测试文档和API文档都没有解释它

我也看到了doWithSpring,但故事是一样的:我不知道如何使用它,但我需要为它创建一个模拟


我使用Grails2.5.0。我是Grails的新手,我迷失在它的一些魔力中

您是否尝试过使用规范中如下所示的
doWithSpring

import grails.test.mixin.support.GrailsUnitTestMixin

@TestMixin(GrailsUnitTestMixin)
@TestFor(ContentService)
class ContentServiceSpec extends Specification {

    static doWithSpring = {
        evaluator(Evaluator)
    }

    def setup() {
        service.evaluator = evaluator
    }

    def "Should test..."() {
       ...
    }

}

有关详细信息,请参阅(不再处于活动状态;新链接引用Grails 3.x,但仍然与dowithspring表示法相关)。

您应该使用dowithspring通过使用
org.codehaus.groovy.Grails.commons.InstanceFactoryBean来添加依赖项的模拟实例

import org.codehaus.groovy.grails.commons.InstanceFactoryBean

@TestFor(ContentService)
class ContentServiceSpec extends Specification {

    static doWithSpring = {
        evaluator(InstanceFactoryBean, Mock(Evaluator), Evaluator)
    }



    def "Should test..."() {
       ...
    }

}

Evaluator
ExperimentEvaluator
看起来怎么样?对不起,我重新编辑了我的答案,但是Evaluator和ExperimentEvaluator是一样的。这段代码来自一个专有代码库,所以我不能简单地将其转储到这里。
Evaluator
类是Java,没有空构造函数。实例化它并不容易,模拟它并将其注入服务(本着单元测试的精神:)会更容易。感谢您的回复。是的,我试过了,但问题是a)Spring找不到Evaluator bean,即使这样,b)我想模拟Evaluator。我怎样才能模仿Evaluator并告诉Spring在Spock单元测试实例化的服务中使用它?如果
Evaluator
不是一个bean,那么它是如何
@Autowired
首先在
ContentService
中声明的bean,但我找不到它的定义位置。我之所以这么认为,是因为它已经在另一个类/测试中使用,并且这些类/测试在测试和运行时都可以顺利工作。但另一个类不是服务,因此不使用
@TestFor
注释以及
服务
对象的spock单元测试自动实例化。如果我将
@TestFor
替换为
@TestMixin
,并手动实例化服务并注入bean,则效果良好。这就是我目前的工作。如果您能在github中提供一个复制此问题的示例应用程序,我将很乐意为您提供帮助。感谢@dmahapatro对此进行研究。由于我找到了一个解决方法(即删除
@TestFor
注释并自己管理依赖项注入),如果我在github中构建一个示例应用程序,那么在这个问题上花费的时间太多了。随着时间的推移,我将更加熟悉我所使用的现有应用程序,因此,也许我会在稍后重新讨论我的问题。再次感谢您抽出时间!