将mock注入bean失败

时间:2011-09-09 11:51:51

标签: spring easymock autowired

对于我的单元测试,我想使用模拟来测试被测bean的一些自动连接依赖项。创建模拟并将其正确注入单元测试类,但是将其注入到测试中的bean中失败

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No matching bean of type [Service] 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)}

这是我用过的testContext.xml

<bean id="Service" class="org.easymock.EasyMock" factory-method="createMock">
    <constructor-arg  value="Service" ></constructor-arg>
</bean>

<bean id="Controller" class="Controller">
    <property name="Service" ref="Service"></property>
</bean>

这是被测bean(Controller.java)中接线失败的部分

@Autowired
private Service service;

但如果我将同一个模拟器自动装入我的单元测试类(ControllerTest.java),则不会发生错误,

@Autowired
private Service service;

注入的对象是

类型
($Proxy18) EasyMock for interface Service

有任何建议为什么注入被测豆不可能,但注入测试工作?

亲切的问候 多米尼克

2 个答案:

答案 0 :(得分:2)

我认为这个问题可能与事情的顺序有关。在ControllerTest中,我猜你正在扩展AbstractJUnit4SpringContextTests或类似的东西,首先连接你的所有bean(在你甚至有机会创建你的模拟之前)。没有看到你的全班(或者至少是类声明,setUp,tearDown和特定的测试方法),很难说。

单元测试(与集成测试相反)通常的做法是不使用spring来连接任何东西 - 只需使用属性设置器手动注入模拟协作者。集成测试通常不使用模拟 - 它们使用真实对象。

有时候,您希望进行集成测试,但是您想要模拟一个特定的协作者,因为真正的协作者会做一些具有破坏性的事情或者发送短信等等。我在这些情况下所做的就是让Spring按照自己想要的方式连接所有内容,然后在所有内容初始化之后使用类中的属性setter手动注入模拟。除非您想要模拟的真实类在初始化中做了一些您真正不想要的东西,否则没有问题。

答案 1 :(得分:1)

这可能与随机效应有关:Spring的bean实例化顺序。

查看应用程序上下文配置片段,spring无法知道它必须首先创建Service类型的模拟对象,因为它不知道具有id Service的bean的实例化将导致类型Service。如果首先创建Controller bean,这可能会阻止自动装配。

要确认这一点,请尝试

<bean id="Controller" class="Controller" depends-on="Service">

(编辑:您在服务的xml配置中使用自动装配和显式属性。如果从Controller.Service中删除@Autowired会怎样?)

在引用@jhericks的旁注中,我们有时会在集成测试中注入模拟对象(在极少数情况下这是绝对必要的)这样:应用程序有一个可选参数(命令行,配置文件左右),其中我们可以为它提供额外的xml应用程序上下文配置文档。这个简短的文档覆盖了有问题的bean的bean声明,用模拟变体替换它。