Spring 如何在针对服务的spock测试中模拟自动连线bean?
我需要将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
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中构建一个示例应用程序,那么在这个问题上花费的时间太多了。随着时间的推移,我将更加熟悉我所使用的现有应用程序,因此,也许我会在稍后重新讨论我的问题。再次感谢您抽出时间!