自动assembly由EasyMock工厂方法生成的bean?
我有一个对我来说真的很奇怪的问题。 我有以下设置:
界面:
package com.example; public interface SomeDependency { }
弹簧组件:
package com.example; @Component public class SomeClass { }
带有由EasyMock生成的模拟bean的spring test配置:
并进行unit testing:
@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生成的模拟对象)的自动assembly成功。
但是,如果我将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无法将依赖关系自动assembly到SomeClass (当它成功自动assembly相同的依赖关系到SomeClassTest时 )?
- 如何更改SomeClassTest或testconfig.xml以使测试通过?
评论:实际上, SomeClass代表的类是框架的一部分。 因此,它不容易更新,至少不能在合理的时间内更新。
依赖关系:
- spring:3.0.5.RELEASE
- EasyMock:3.0
编辑:
从Spring 3.2 RC1开始,通用工厂方法和模拟对象的问题已经解决 。
/马蒂亚斯
当使用工厂创建具有自动assembly的bean时,似乎xml中定义的顺序实际上很重要。 如果将someInterfaceMock
的声明someInterfaceMock
component-scan
之上,它将起作用。
一些澄清原因:当Spring尝试自动assemblySomeClass
它会搜索SomeDependency
类型的bean。 在这个阶段, someInterfaceMock
仍然是一个工厂,所以Spring检查工厂方法EasyMock.createMock(...)
的签名,它返回
所以Spring只找到一个不是所需类型的Object
。
更好的方法是使用Spring的FactoryBean
接口来创建FactoryBean
。
这是一个应该工作的基本实现:
public class EasyMockFactoryBean implements FactoryBean { private Class mockedClass; public void setMockedClass(Class mockedClass) { this.mockedClass = mockedClass; } public T getObject() throws Exception { return EasyMock.createMock(mockedClass); } public Class getObjectType() { return mockedClass; } public boolean isSingleton() { return true; } }
这是bean定义(顺序无关紧要!):
- spring – ApplicationContext registerBean自动assembly失败,但getBean在Spring 5中工作
- 使用@Autowired将依赖项注入使用“new …”创建的对象中
- 自动assembly:预计至少有一个bean可以作为此依赖关系的autowire候选者
- 在没有弹簧实例化的类中支持自动assembly(3)
- Spring @Autowired – 实例化新bean
- @Autowired HttpServletResponse
- 无法自动assembly方法
- Spring Boot – 环境@Autowired抛出NullPointerException
- @Autowired注释在Java中的好处