Я хотел бы ввести фиктивный объект Mockito в Spring (3 +) боб в целях поблочного тестирования с JUnit. Мои бобовые зависимости в настоящее время вводятся при помощи @Autowired
аннотация на поля члена парламента, не занимающего официального поста.
Я рассмотрел использование ReflectionTestUtils.setField
но бобовый экземпляр, который я хочу ввести, является на самом деле прокси и следовательно не объявляет поля члена парламента, не занимающего официального поста целевого класса. Я не хочу создавать общедоступный метод set к зависимости, поскольку я буду затем изменять свой интерфейс просто в целях протестировать.
Я последовал некоторому совету, данному сообществом Spring, но насмешка не становится созданной и сбои автопроводного соединения:
Ошибка, с которой я в настоящее время встречаюсь, следующие:
...
Caused by: org...NoSuchBeanDefinitionException:
No matching bean of type [com.package.Dao] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {
@org...Autowired(required=true),
@org...Qualifier(value=dao)
}
at org...DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(D...y.java:901)
at org...DefaultListableBeanFactory.doResolveDependency(D...y.java:770)
Если я установил constructor-arg
оцените чему-то недопустимому, никакая ошибка не происходит при запуске контекста приложения.
Возможно, не идеальное решение, но я стараюсь не использовать Spring для выполнения DI для модульных тестов. зависимости для одного bean-компонента (тестируемого класса) обычно не слишком сложны, поэтому я просто выполняю инъекцию непосредственно в тестовом коде.
Update: Теперь есть лучшие, более чистые решения этой проблемы. Пожалуйста, сначала рассмотрите другие ответы.
В конце концов я нашел ответ на этот вопрос роненом в своем блоге. Проблема, с помощью которого я оказался, связана с тем, что метод Mockito.mock(Class c)
, объявляющий возвращаемый тип Object
. Следовательно, Spring не может вывести тип бобов из типа возврата фабричного метода.
Решение Ронена состоит в том, чтобы создать реализацию FactoryBean
, которая возвращает макеты.Интерфейс FactoryBean
позволяет Spring запрашивать тип объектов, создаваемых заводским компонентом.
Моё насмешливое определение боба теперь выглядит так:
<bean id="mockDaoFactory" name="dao" class="com.package.test.MocksFactory">
<property name="type" value="com.package.Dao" />
</bean>
Я могу сделать следующее, используя Mockito:
<bean id="stateMachine" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.abcd.StateMachine"/>
</bean>
Лучший способ:
<bean id="dao" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.package.Dao" />
</bean>
Обновить
В контекстном файле этот макет должен быть указан перед объявлением любого автоматически связанного поля, в зависимости от его объявления.