Junit 4 не может видеть боб - PullRequest
       2

Junit 4 не может видеть боб

1 голос
/ 18 октября 2011

Я использую @Bean и @Annotation в своих классах так:

@Transactional
@Configuration
public class UserDAO {

    @Bean
    public UserDAO userDAO()
    {
        return new UserDAO();
    }
    private HibernateTemplate hibernateTemplate;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.hibernateTemplate = new HibernateTemplate(sessionFactory);
    }

    public void Save(User s){
        this.hibernateTemplate.save(s);
    }
}

Вот мой spring-servlet.xml. Обратите внимание, что я не пишу никаких бинов типа 'userDAO':

<?xml  version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    (...)

    <context:annotation-config />
    <tx:annotation-driven transaction-manager="txManager" />
    <bean id="txManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean>
    <bean id="jspViewResolver"
        (...)
    </bean>

    <bean id="pdfViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
            (...)
    </bean> 

    <bean
        class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

    <bean class="org.springframework.jmx.export.MBeanExporter">
        <property name="autodetect" value="false" />
        <property name="assembler">
            <bean id="jmxAssembler"
                class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
                <property name="attributeSource">
                    <bean
                        class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
                </property>
            </bean>
        </property>

    </bean>
    <context:component-scan base-package="pl.edm.taskcards.spring" />
    <context:component-scan base-package="pl.raban.resource.spring" />

    <bean id="messageSource"
        class="org.springframework.context.support.ResourceBundleMessageSource"
        p:basename="messages" />

    <bean id="openSessionInViewInterceptor"
        class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>


    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        (...)
    </bean>




    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan">
            <list>
                <value>pl.edm.taskcards.spring</value>
                <value>pl.raban.resource.spring</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.connection.useUnicode">true</prop>
                <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
                <prop key="hibernate.jdbc.batch_size">0</prop>
                <prop key="hibernate.query.substitutions">true 1, false 0</prop>
            </props>
        </property>
    </bean>
    <tx:annotation-driven />

</beans>

Все работало нормально, я могу сохранить пользователя в моем веб-приложении. Теперь я хочу сделать простой тест, подобный этому:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration (locations = {"classpath:**/spring-servlet.xml"})
@DependsOn("UserDAO")
@Transactional
@Configuration
public class UserDAOTest extends AbstractTransactionalDataSourceSpringContextTests {

    @Autowired
    private UserDAO userDAO;
    @Autowired
    private SessionFactory sessionFactory;

    public UserDAO getUserDAO() {
        return userDAO;
    }
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
    public SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }


    @Test
    public void testSave() {
        User spr = new User();
        spr.setKzId(0);
        spr.setOpis("User test");
        spr.setPlan("Plan test");
        spr.setPolrocze(1);
        spr.setPrognoza1("test1");
        spr.setPrognoza2("test2");
        spr.setRok(2000);
        userDAO.Save(spr);
        User spr2 = userDAO.GetUserById(spr.getId());
        Assert.assertEquals("User test", spr2.getOpis());
    }

}

Но после запуска этого теста я получил ошибку:

<code>> <pre>org.springframework.beans.factory.BeanCreationException: Error
> creating bean with name 'pl.edm.taskcards.spring.UserDAOTest':
> Injection of autowired dependencies failed; nested exception is
> org.springframework.beans.factory.BeanCreationException: Could not
> autowire field: private pl.edm.taskcards.spring.UserDAO
> pl.edm.taskcards.spring.UserDAOTest.userDAO; nested exception is
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No
> matching bean of type [pl.edm.taskcards.spring.UserDAO] 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)}
>     at
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
>     at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
>     at
> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374)
>     at
> org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)
>     at
> org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
>     at
> org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:321)
>     at
> org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)    at
> org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
>     at
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
>     at
> org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
>     at
> org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
>     at
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
>     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)  at
> org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)     at
> org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)   at
> org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)     at
> org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)    at
> org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
>     at
> org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
>     at org.junit.runners.ParentRunner.run(ParentRunner.java:236)    at
> org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
>     at
> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
>     at
> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>     at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
>     at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
>     at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
>     at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> Caused by: org.springframework.beans.factory.BeanCreationException:
> Could not autowire field: private pl.edm.taskcards.spring.UserDAO
> pl.edm.taskcards.spring.UserDAOTest.userDAO; nested exception is
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No
> matching bean of type [pl.edm.taskcards.spring.UserDAO] 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)}
>     at
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
>     at
> org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
>     at
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
>     ... 26 more  Caused by:
> org.springframework.beans.factory.NoSuchBeanDefinitionException: No
> matching bean of type [pl.edm.taskcards.spring.UserDAO] 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)}
>     at
> org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924)
>     at
> org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793)
>     at
> org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
>     at
> org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
>     ... 28 more

Ответы [ 3 ]

3 голосов
/ 18 октября 2011

Я думаю, что вы путаете некоторые механизмы здесь.Класс @Configuration предоставляет компоненты, но не должен быть самим компонентом.

Либо используйте @Component для непосредственного создания компонента, либо поместите аннотацию @Configuration в другом классе.

Узнайте больше о понятиях:

a) 3.10.Сканирование пути к классам и управляемые компоненты
b) 3.11.Конфигурация контейнера на основе Java

Но он все равно должен работать, даже если вы путаете понятия.

Однако проблема должна заключаться в следующем:

@ContextConfiguration (locations = {"classpath:**/spring-servlet.xml"})

Две проблемы:
a) подстановочные знаки в начале ресурса Строки проблематичны
b) если ваш весенний контекст находится в WEB-INF, он не находится на пути к классу и, следовательно, не можетбыть найденным "classpath:**/spring-servlet.xml".Я не знаю, каков канонический способ доступа к такому контексту в модульном / интеграционном тесте, но я бы попробовал что-то вроде этого:

@ContextConfiguration (locations = {
    "file:/src/main/webapp/WEB-INF/spring-servlet.xml"})

(см. FileSystemResource предостережения )

2 голосов
/ 18 октября 2011

Где находится файл spring-servlet.xml - я предполагаю, что он находится в WEB-INF, если это так, вы не можете загрузить его с помощью classpath: как вы делаете в тестовом классе?

0 голосов
/ 18 октября 2011

Вам необходимо объявить bean-компонент для класса UserDao.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...