Announcement Announcement Module
Collapse
No announcement yet.
JUnit 4 Tests don't work with Spring 3, @Inject, @Service annotations Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • JUnit 4 Tests don't work with Spring 3, @Inject, @Service annotations

    Most Tests and examples include an xml config file. I have a project setup mostly with annotations and base spring 3 config. I can't get the tests to run since I get an error that no matching bean of type is found:


    Caused by:
    Code:
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [xxx.service.ProfileService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.inject.Inject()}
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920)
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789)
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:474)
     ... 28 more

    applicationContext-core.xml
    Code:
     
    <beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
     xmlns:aop="http://www.springframework.org/schema/aop"        
     xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schem...-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schem...ontext-3.0.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schem...ing-tx-3.0.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schem...ng-aop-3.0.xsd        
            http://www.springframework.org/schema/util
            http://www.springframework.org/schem...g-util-3.0.xsd">
     <context:annotation-config />
     
     <aop:aspectj-autoproxy />
     <context:component-scan base-package="xxx" />
     
    <tx:annotation-driven transaction-manager="transactionManager" />
      <bean
      class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
     <bean id="loadTimeWeaver"
      class="org.springframework.instrument.classloading.SimpleLoadTimeWeaver" />
     <bean id="jdbcDataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver" />
      <property name="url" value="jdbc:mysql://localhost:3306/tcms" />
      <property name="username" value="root" />
      <property name="password" value="root" />
     </bean>
     
     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
         p:entity-manager-factory-ref="entityManagerFactory" />
     <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:persistence-xml-location="classpath*:META-INF/persistence.xml"
        p:persistence-unit-name="profile" 
        p:data-source-ref="jdbcDataSource"
        p:jpaVendorAdapter-ref="jpaVendorAdapter" 
        p:jpaDialect-ref="jpaDialect"
        p:loadTimeWeaver-ref="loadTimeWeaver">
     </bean>
     
     <bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.OpenJpaDialect" />
     
    <!-- OpenJPA adapter -->
     <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter">
         <property name="database" value="MYSQL" />
         <property name="showSql" value="true" />
         <property name="generateDdl" value="true" />
     </bean>
    </beans>
    persistence.xml
    Code:
     
    
    <persistence-unit name="profile" transaction-type="RESOURCE_LOCAL" > <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <class>xxx.entity.BMSProfile</class> <properties> <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> </properties> </persistence-unit> </persistence>
    ProfileServiceImpl.java
    Code:
    @Service("profileService") public class ProfileServiceImpl implements ProfileService {
    @PersistenceContext EntityManager em;
    final EmailService emailService;
    // Not used unless you declare a <protect-pointcut> @Pointcut("execution(* xxx.ProfileServiceImpl.*(..))") public void myPointcut() { }
    @Inject public ProfileServiceImpl(final EmailService emailService) { this.emailService = emailService; }
    public List<BMSProfile> findAccounts() { return em.createNamedQuery("findAllAccounts").getResultList(); }
    public List<BMSProfile> findAccountById(Long abnId) { return em.createNamedQuery("findAccountById").setParameter("abnId", abnId).getResultList(); }
    public BMSProfile post(BMSProfile account) { return null; }
    public BMSProfile readAccount(Long id) { return em.find(BMSProfile.class, id); }
    }
    Testclass
    Code:
    @RunWith
    
    (SpringJUnit4ClassRunner.class)
    @ContextConfiguration (locations = {
    "classpath*:applicationContext-core.xml", "classpath*:applicationContext-mail.xml", "classpath*:applicationContext-security.xml" }) @TransactionConfiguration @Transactional public class ProfileServiceTest {
    @Inject private ProfileService profileService; @Test publicvoid testSave() { List<BMSProfile> list = profileService.findAccounts(); assertEquals(list.size(), 1); }
    }


    As you can see, it's a straight forward Spring app using JSR330 injections and <context:annotation-config /> and <context:component-scan/> is setup in spring-core as well. It doesn't make a difference if @Autowired is used instead of @Inject.

    Also, the config files are in the classpath while junit tests are running.

    I got this working in 2.5x in my earlier projects. What am I missing here?
    Last edited by infinity2heaven; Mar 7th, 2011, 06:11 PM. Reason: added testclass

  • #2
    I assume that ProvileServiceImpl is in package xxx? What does your JUnit test look like? Did you ensure to add the @ContextConfiguration with the appropriate xml file locations? Does it work if you remove Spring Security (if so in the future it might be a better question for one of the other Spring forums)? If you make the xml invalid do you get an error when running the test (ensures you are loading the xml)?

    Comment


    • #3
      Fixed now. Turned out to be yet another classpath issue. Apparently, Spring didn't error on file not found earlier. I had to add spring/applicationContext-*.xml in the @ContextConfiguration

      Comment

      Working...
      X