2011-06-14 4 views
14

У меня есть проблема, которая кажется мне очень странной. У меня есть следующие настройки:Автомашина фасоли, произведенная фирменным методом EasyMock?

Интерфейс:

package com.example; 

public interface SomeDependency { 
} 

Пружинный компонент:

package com.example; 

@Component 
public class SomeClass { 
} 

Пружинный тест конфигурации с Посмешищем бобов, генерируемого EasyMock:

<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. Почему весна неудачу для автоподключения зависимости от SomeClass (когда удастся выполнить автоподключение той же зависимости до SomeClassTest)?
  2. Как я могу изменить SomeClassTest или testconfig.xml, чтобы пройти тесты?

Комментарий: В действительности класс представлен SomeClass является частью структуры. Следовательно, он не может быть легко обновлен, по крайней мере, не в разумные сроки.

Зависимости:

  • Весна: 3.0.5.RELEASE
  • EasyMock: 3,0

Edit:

С весны 3.2 RC1, проблема с родовым завода методы и макет объектов - solved.

/Маттиас

ответ

20

Кажется, порядок определений в XML на самом деле важно, когда с помощью фабрики для создания бобов автоматического связывания. Если вы разместите объявление someInterfaceMock выше component-scan, оно будет работать.

Некоторые разъяснения почему: Когда весна пытается autowire SomeClass, он ищет фасоль типа SomeDependency. На этом этапе someInterfaceMock по-прежнему является фабрикой, поэтому Spring проверяет подпись заводского метода EasyMock.createMock(...), который возвращает <T>, поэтому Spring находит только Object, который не является требуемым типом.

Лучшим способом было бы использовать интерфейс Spring FactoryBean, чтобы создавать ваши mocks.

Вот базовая реализация, которая должна работать: (! Порядок не имеет значения)

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>  
+0

Спасибо! Приказ сделал трюк, но я думаю, что я буду использовать реализацию EasyMockFactoryBean, учитывая, что, вероятно, мне придется позже высмеять другие зависимости. – matsev

Смежные вопросы