代码之家  ›  专栏  ›  技术社区  ›  andrea

使用spring3+junit4+mybatis进行测试时出现自动布线服务错误

  •  0
  • andrea  · 技术社区  · 13 年前

    我对使用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,但它得到了一个null值。

    我的配置和类是

    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 ....
    

    mapper类

    @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 回复  |  直到 13 年前
        1
  •  2
  •   andrea    13 年前

    解决了的。。。问题是我试图在没有接口的情况下自动连接一个具体的bean

    感谢所有回复:-)

    安德里亚

        2
  •  1
  •   spiritwalker    13 年前

    从更改自动连接的代码

    @Autowired
    private MailReceiverAccountService mailReceiverAccountService;
    

    @Autowired
    private DaoService mailReceiverAccountService;
    

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

        3
  •  0
  •   Dhanush Gopinath    13 年前

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

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