JUnit中的嵌套自动装配测试无法正常工作

时间:2014-06-10 12:46:07

标签: java spring junit jdbctemplate spring-annotations

我正在使用JavaFX开发一个spring应用程序(我使用Spring MVC NOT )并且我将控制器 - 服务 - DAO的标准分离。我正在使用JdbcTemplate。我愿意为我的一个服务写下jUnit测试(我已经为其中一些服务做过了)。具体的事情是该服务是自动装配两个DAO(其中一个DAO本身使用事务),而且它有一个方法,@Transactional。这就是我的测试看起来如何:

package org.impactvolunteers.management.service.impl;

imports ...;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:testContext.xml" })
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class RegisterVolunteerServiceImplTest extends
        AbstractRegisterVolunteerServiceTest {
    @Autowired
    private RegisterVolunteerService registerVolunteerService;

    @Before
    public void setUp() {
        setRegisterVolunteerService(registerVolunteerService);
    }

}

我的服务实施:

package org.impactvolunteers.management.service.impl;

imports ...;

public class RegisterVolunteerServiceImpl implements RegisterVolunteerService {
    @Autowired
    private VolunteerDao volunteerDao;

    @Autowired
    private UserDao userDao;

    @Transactional(rollbackFor = { ServiceException.class,
            ValidationException.class })
    public Volunteer registerVolunteer(User user, Volunteer volunteer)
            throws ServiceException, ValidationException {
        UserValidator.validateData(user);
        VolunteerValidator.validateData(volunteer);
        try {
            User ret = userDao.create(user);
            volunteer.setUser(ret);
            return volunteerDao.create(volunteer);
        } catch (PersistenceException e) {
            throw new ServiceException(e.getMessage(), e);
        }
    }
}

在应用程序 - 上下文中:

<context:component-scan base-package="org.impactvolunteers.management"/>

    <!-- enable the configuration of transactional behavior based on annotations -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

    <!-- Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    ...
    <bean id="registerVolunteerService" class="org.impactvolunteers.management.service.impl.RegisterVolunteerServiceImpl" >
    </bean>

以下是错误消息:

  

org.springframework.beans.factory.BeanCreationException:使用name创建bean时出错   'org.impactvolunteers.management.service.impl.RegisterVolunteerServiceImplTest':   注入自动连接的依赖项失败;嵌套异常是   org.springframework.beans.factory.BeanCreationException:不能   autowire字段:私有   org.impactvolunteers.management.service.RegisterVolunteerService   org.impactvolunteers.management.service.impl.RegisterVolunteerServiceImplTest.registerVolunteerService;   嵌套异常是   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   合格的bean类型   [org.impactvolunteers.management.service.RegisterVolunteerService]   找到依赖:预计至少有1个bean符合条件   autowire候选人这种依赖。依赖注释:   {@ org.springframework.beans.factory.annotation.Autowired(所需=真)}         在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)         ............       引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   合格的bean类型   [org.impactvolunteers.management.service.RegisterVolunteerService]   找到依赖:预计至少有1个bean符合条件   autowire候选人这种依赖。依赖注释:   {@ org.springframework.beans.factory.annotation.Autowired(所需=真)}         at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988)         at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858)         在org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770)         at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)         ......还有28个

我的test-Context.xml:

    <context:annotation-config/>

    <context:component-scan base-package="org.impactvolunteers.management"/>

    <bean id="jdbc" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- Spring JDBC Utility for in-memory database -->
    <jdbc:embedded-database id="dataSource" type="HSQL"/>

我注意到两件奇怪的事情:

  1. 启动应用程序作为Java应用程序并且服务按预期工作没有问题。我只是将服务测试为jUnit测试。
  2. 具有完全相同的上下文的服务(以及与此处显示的测试相同的测试上下文)和bean定义正在成功测试,唯一的区别是它不包含@Transactional注释,其中一些它下面的DAO(实现VolunteerDaoImpl的{​​{1}}确实包含VolunteerDao注释。

2 个答案:

答案 0 :(得分:2)

必须将班级RegisterVolunteerServiceImpl注释为服务。

如果类没有注释为服务,则组件扫描不会发现它。所以名称的bean不是实例化的,不能自动装配。

在主应用程序上下文中,添加没有组件扫描的bean

 <bean id="registerVolunteerService" class="org.impactvolunteers.management.service.impl.RegisterVolunteerServiceImpl" >
    </bean>

答案 1 :(得分:1)

testContext.xml没有导入您的通用应用程序上下文,也没有定义registerVolunteerService bean。