mat*_*sev 14 java spring easymock factory-method autowired
我有一个看起来很奇怪的问题.我有以下设置:
界面:
package com.example;
public interface SomeDependency {
}
弹簧组件:
package com.example;
@Component
public class SomeClass {
}
带有由EasyMock生成的模拟bean的spring test配置:
<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)}
所以我的问题是:
评论:实际上,SomeClass代表的类是框架的一部分.因此,它不容易更新,至少不能在合理的时间内更新.
依赖关系:
编辑:
从Spring 3.2 RC1开始,通用工厂方法和模拟对象的问题已经解决.
/马蒂亚斯
Wil*_*leu 21
当使用工厂创建具有自动装配的bean时,xml中的定义顺序似乎很重要.如果你把申报someInterfaceMock上述component-scan它将工作.
一些澄清原因:当Spring尝试自动装配时,SomeClass它会搜索类型的bean SomeDependency.在这个阶段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>    
| 归档时间: | 
 | 
| 查看次数: | 12344 次 | 
| 最近记录: |