自动装配由 EasyMock 工厂方法生成的 bean?
Posted
技术标签:
【中文标题】自动装配由 EasyMock 工厂方法生成的 bean?【英文标题】:Autowiring of beans generated by EasyMock factory-method? 【发布时间】:2011-09-14 11:07:24 【问题描述】:我有一个对我来说似乎很奇怪的问题。我有以下设置:
一个接口:
package com.example;
public interface SomeDependency
一个弹簧组件:
package com.example;
@Component
public class SomeClass
带有由 EasyMock 生成的模拟 bean 的弹簧测试配置:
<beans ....>
<context:component-scan base-package="com.example"/>
<bean id="someInterfaceMock" class="org.easymock.EasyMock" factory-method="createMock">
<constructor-arg value="com.example.SomeDependency" />
</bean>
</beans>
还有一个单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/testconfig.xml")
public class SomeClassTest
@Autowired
SomeClass someClass;
@Autowired
SomeDependency someDependency;
@Test
public void testSomeClass() throws Exception
assertNotNull(someClass);
@Test
public void testSomeDependency() throws Exception
assertNotNull(someDependency);
项目编译并且测试通过没有任何问题,即自动装配SomeClass(一个“真实”对象)和SomeDependency(一个由EasyMock生成的模拟对象)成功。
但是,如果我将 SomeClass 的实现更改为:
@Component
public class SomeClass
@Autowired
SomeDependency someDependency;
两个测试都失败了,因为
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.example.SomeDependency] 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)
所以我的问题是:
-
为什么 Spring 无法将依赖项自动装配到 SomeClass(当它成功地将相同的依赖项自动装配到 SomeClassTest 时)?
如何更改 SomeClassTest 或 testconfig.xml 以使测试通过?
评论:实际上,SomeClass 所代表的类是框架的一部分。因此,它不能轻易更新,至少不能在合理的时间内更新。
依赖关系:
春季:3.0.5.RELEASE EasyMock:3.0编辑:
从 Spring 3.2 RC1 开始,泛型工厂方法和模拟对象的问题一直是 solved。
/马蒂亚斯
【问题讨论】:
【参考方案1】:在使用工厂创建具有自动装配功能的 bean 时,xml 中定义的顺序似乎很重要。如果您将someInterfaceMock
的声明放在component-scan
上方,它将起作用。
解释一下原因:当 Spring 尝试自动装配 SomeClass
时,它会搜索 SomeDependency
类型的 bean。在这个阶段,someInterfaceMock
仍然是一个工厂,所以 Spring 检查工厂方法 EasyMock.createMock(...)
的签名,它返回 <T>
,所以 Spring 只找到一个不是所需类型的 Object
。
更好的方法是使用 Spring 的 FactoryBean
接口来创建你的模拟。
这是一个应该可以工作的基本实现:
public class EasyMockFactoryBean<T> implements FactoryBean<T>
private Class<T> mockedClass;
public void setMockedClass(Class mockedClass)
this.mockedClass = mockedClass;
public T getObject() throws Exception
return EasyMock.createMock(mockedClass);
public Class<T> getObjectType()
return mockedClass;
public boolean isSingleton()
return true;
这是 bean 定义(顺序无关紧要!):
<bean class="com.example.EasyMockFactoryBean">
<property name="mockedClass" value="com.example.Dependancy"/>
</bean>
【讨论】:
谢谢!该命令起到了作用,但我认为我将使用 EasyMockFactoryBean 实现,考虑到我以后可能必须模拟其他依赖项。以上是关于自动装配由 EasyMock 工厂方法生成的 bean?的主要内容,如果未能解决你的问题,请参考以下文章
4.AutowireCapableBeanFactory 自动装配工厂
AutowireCapableBeanFactory 根据名称:自动装配的BeanFactory,其实也是对BeanFactory的增强
Spring 依赖注入(DI)详解 [Spring][依赖注入的 6 种实现方式][setter注入][构造器注入][注解注入][自动装配注入][静态工厂注入][实例工厂注入]