使用spring 3 + junit 4 + mybatis测试中的错误自动装配服务

时间:2013-03-05 07:38:36

标签: spring junit mybatis

我使用junit 4.10和mybatis进行了春季3测试的问题。我无法在测试课程中自动提供服务。

这是我得到的例外

Running it.infora.suap.service.MailReceiverAccountServiceTest
16:58:24,933  INFO TestContextManager:185 - @TestExecutionListeners is not present for class [class it.infora.suap.service.MailReceiverAccountServiceTest]: using defaults.
16:58:25,157  INFO XmlBeanDefinitionReader:315 - Loading XML bean definitions from class path resource [testApplicationContext.xml]
16:58:25,535  INFO GenericApplicationContext:500 - Refreshing org.springframework.context.support.GenericApplicationContext@17a6a4b: startup date [Mon Mar 04 16:58:25 CST 2013]; root of context hierarchy
16:58:25,740  INFO DefaultListableBeanFactory:581 - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1a390f4: defining beans [mailReceiverAccountBean,mailReceiverAccountService,mailMessageService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,transactionManager,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,dataSource,sqlSessionFactory,sqlSession,org.mybatis.spring.mapper.MapperScannerConfigurer#0,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0,mailMessageMapper,mailReceiverAccountMapper]; root of factory hierarchy
16:58:26,732 ERROR TestContextManager:324 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@823b18] to prepare test instance [it.infora.suap.service.MailReceiverAccountServiceTest@1f5c8d2]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'it.infora.suap.service.MailReceiverAccountServiceTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private it.infora.suap.service.MailReceiverAccountService it.infora.suap.service.MailReceiverAccountServiceTest.mailReceiverAccountService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [it.infora.suap.service.MailReceiverAccountService] 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:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    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:288)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private it.infora.suap.service.MailReceiverAccountService it.infora.suap.service.MailReceiverAccountServiceTest.mailReceiverAccountService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [it.infora.suap.service.MailReceiverAccountService] 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:506)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    ... 32 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [it.infora.suap.service.MailReceiverAccountService] 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:952)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:821)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
    ... 34 more

我尝试在springBean文件中手动注册bean,但是它获得了一个空值。

我的配置和类是

的pom.xml

<properties>
        <spring.version>3.1.2.RELEASE</spring.version>     
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <repositories>
        <repository>
            <id>JBoss repository</id>
            <url>http://repository.jboss.com/maven2/</url>
        </repository>
    </repositories>

    <dependencies>

        <!-- PostgeSQL -->
        <dependency>
            <groupId>postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.1-901.jdbc4</version>
        </dependency>    

        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- JSP dependacy -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

        <!-- Apache Commons Upload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.2</version>
        </dependency>

        <!-- Apache Commons Upload -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1-b01</version>
        </dependency> 

        <!-- Ibatis -->  
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.0</version>
        </dependency>  
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.0</version>
        </dependency>        
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <!-- JUnit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>MailClient</artifactId>
            <version>${project.version}</version>
        </dependency>     

    </dependencies>

applicationContext.xml(用于测试)

<context:component-scan base-package="it.infora.suap" />

        <!-- enable autowire -->
    <context:annotation-config  />

    <!-- transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>    

        <!-- enable transaction demarcation with annotations -->
    <tx:annotation-driven transaction-manager="transactionManager" />

    <!-- Declare a datasource that has pooling capabilities -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close" p:driverClassName="org.postgresql.Driver" p:url="jdbc:postgresql://localhost:5432/suap"
        p:username="userSuap" p:password="us3rsu@p" p:defaultAutoCommit="false" />


        <!-- define the SqlSessionFactory -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="typeAliasesPackage" value="it.infora.suap.model"/>
            <!--property name="configLocation" value="META-INF/mybatis-config.xml" /-->
            <property name="typeHandlersPackage" value="it.infora.suap.handler"/>

        </bean>        

        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
         <constructor-arg index="0" ref="sqlSessionFactory" />
        </bean>        

        <!-- scan for mapper interface files and let them be autowired -->
     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
      <property name="basePackage" value="it.infora.suap.persistence" />
     </bean> 

我的模特课

@Component
public class MailReceiverAccountBean implements MailReceiverAccount {

    private Integer id;
    private String username;
    private String password;
//    private String email;
    private String serverAddress;
    private Integer serverPort;
    private MailProtocol mailProtocol;
//    private String name;
    private Boolean encrypted;
    private MailEncryptionType encryptionType;
    private String accountName;

omitted getter and setter ....

映射器类

@Repository
public interface MailReceiverAccountMapper {

    @Insert("INSERT INTO email_account(username, password, server_address, server_port, mail_protocol, account_name, encrypted, encryption_type)"
            + " VALUES(#{username}, #{password}, #{serverAddress}, #{serverPort}, #{mailProtocol, javaType=MailProtocol.class, jdbcType=JdbcType.VARCHAR, typeHandler=MailProtocolEnumHandler.class},"
            + " #{accountName}, #{encrypted}, #{encryptionType, javaType=MailProtocol.class, jdbcType=JdbcType.VARCHAR, typeHandler=MailEncryptionTypeEnumHandler.class})")
//    @Options(useGeneratedKeys = true, keyProperty = "id")
    public void insertEmailAccount(MailReceiverAccountBean mailReceiverAccountBean);

.........

服务类

@Service("mailReceiverAccountService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class MailReceiverAccountService implements DaoService<MailReceiverAccountBean>{

    @Autowired
    private SqlSession sqlSession;

    @Override
    public void save(MailReceiverAccountBean entity) {
        MailReceiverAccountMapper mailReceiverAccountMapper = sqlSession.getMapper(MailReceiverAccountMapper.class);
        mailReceiverAccountMapper.insertEmailAccount(entity);
    }
       ............

测试类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:testApplicationContext.xml")
public class MailReceiverAccountServiceTest {

    @Autowired
    private MailReceiverAccountService mailReceiverAccountService;


    /**
     * Test of save method, of class EmailAccountService.
     */
    @Test
    public void testSave() {
        System.out.println("save");
        MailReceiverAccountBean ea = this.getFilledEntity();
        mailReceiverAccountService.save(ea);

        Assert.assertTrue(ea.getId() != 0);

        MailReceiverAccountBean created = mailReceiverAccountService.findById(ea.getId());
        Assert.assertNotNull(created);
        Assert.assertEquals(ea, created);        
    }

怎么了?我失去了一些配置吗? 提前谢谢

安德烈

3 个答案:

答案 0 :(得分:2)

解决了...问题是我试图自动装配没有接口的具体bean

感谢大家的回复: - )

安德烈

答案 1 :(得分:1)

更改自动装配的代码
@Autowired
private MailReceiverAccountService mailReceiverAccountService;

@Autowired
private DaoService mailReceiverAccountService;

如果您有多个DaoService实现类,请使用@Qualifier和@Autowired来区分它们。

答案 2 :(得分:0)

在上下文xml中,您没有提供用于扫描带注释的组件的基本包。因此,您的服务类不会被扫描和自动装配。请将此条目添加到上下文

<context:annotation-config />
<context:component-scan base-package="basepackage" />