由EasyMock工厂方法生成的豆子的自动布线?

我有一个问题,对我来说真的很奇怪。我有以下设置:

接口:

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)}

所以我的问题是:

  1. 为什么Spring无法将依赖项自动连接到SomeClass(当它成功地将相同的依赖项自动连接到SomeClassTest时)?
  2. 如何更改 SomeClassTesttestconfig.xml以使测试通过?

评论:实际上,SomeClass所代表的类是框架的一部分。因此,它不容易更新,至少不能在合理的时间内更新。

依赖:

  • 春季: 3.0.5.发布
  • 易上手:3.0

编辑:

从 Spring 3.2 RC1 开始,通用工厂方法和模拟对象的问题已经解决

/马蒂亚斯


答案 1

似乎在使用工厂创建具有自动布线的bean时,xml中定义的顺序实际上很重要。如果你把上面的声明,它将工作。someInterfaceMockcomponent-scan

一些澄清原因:当Spring尝试自动连接时,它会搜索类型为.在这个阶段仍然是一个工厂,所以Spring检查工厂方法的签名,该方法返回,所以Spring只找到一个不是所需类型的。SomeClassSomeDependencysomeInterfaceMockEasyMock.createMock(...)<T>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 class="com.example.EasyMockFactoryBean">
    <property name="mockedClass" value="com.example.Dependancy"/>
</bean>    

答案 2

推荐