Announcement Announcement Module
Collapse
No announcement yet.
Unit Test Issue: @ContextConfiguration, Multiple AppContext Files & Autowiring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unit Test Issue: @ContextConfiguration, Multiple AppContext Files & Autowiring

    We're experiencing a troublesome issue when running all of our unit tests via command line (first via maven, now via gradle).

    We have two broad families of unit tests.
    • We have some unit tests which are pretty close to pure java (no webservice dependencies, no db dependencies, no JMS dependencies, etc).
    • We have other unit tests which depend on much more of our stack (webservices, DB, JMS, etc).

    We have different applicationContext files for these two types of unit tests. For example, the simple tests may have something like :

    Code:
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration({
            "classpath:META-INF/spring/applicationContext-barebones.xml"
    })
    public class SimpleTest  { 
       /* ... */ 
    }
    Whereas the unit tests which depend on more of the stack look like this :
    Code:
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration({
            "classpath:META-INF/spring/applicationContext-fullStack.xml"
    })
    public class ComplexTest  { 
       /* ... */ 
    }
    The troublesome behavior we see is this.
    • we can run all of the tests individually (one at a time), and they succeed
    • we can run all SimpleTests together, and they succeed
    • we can run all of the ComplexTests together, and they succeed
    • if we try to run ALL of the tests together (that is, all of the SimpleTests and all of the ComplexTests, together at once), then we get some failures with the autowiring.

    The failures invariably happen in the autowiring of dependencies of something used by a ComplexTest. For example : ComplexTest1 uses FooService, which has an autowired dependency on a JdbcTemplate - the error is a failure to wire JdbcTemplate (JdbcTemplate is defined in applicationContext-fullStack.xml, but not applicationContext-barebones.xml).

    I think it boils down to this : For the ComplexTests, we need everything defined in applicationContext-fullStack.xml. When running all of the tests together, it seems like the autowiring sometimes gets confused and uses ONLY the beans defined in applicationContext-barebones.xml when doing the autowiring.

    We can fix the problem by making ALL of our tests use applicationContext-fullStack.xml, but this greatly slows down the simple tests with minimal dependencies.

    Any ideas...?

    ---

    We're using
    • spring 3.0.3 release
    • JDK 1.6
    • junit 4.7

    Example snippet from applicationContext-fullStack.xml (narrowed it down for readability)
    Code:
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:jaxws="http://cxf.apache.org/jaxws"
           xmlns:amq="http://activemq.apache.org/schema/core"
           xsi:schemaLocation="
              http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
              http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
              http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
              http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
              http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
              http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    
    
       <context:property-placeholder location="classpath*:META-INF/spring/AppServer.properties"/>
    
       <context:spring-configured/>
    
       <context:annotation-config/>
    
    
    
       <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" id="hibernateDialect"/>
    
       <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
          <property name="entityManagerFactory" ref="entityManagerFactory"/>
          <property name="jpaDialect" ref="hibernateDialect"/>
       </bean>
    
       <tx:annotation-driven mode="aspectj" transaction-manager="transactionManager"/>
    
       <bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
          <property name="driverClassName" value="${database.driverClassName}"/>
          <property name="url" value="${database.url}"/>
          <property name="username" value="${database.username}"/>
          <property name="password" value="${database.password}"/>
          <property name="maxActive" value="${database.pool.maxActive}"/>
          <property name="maxIdle" value="${database.pool.maxIdle}"/>
          <property name="minIdle" value="${database.pool.minIdle}"/>
          <property name="initialSize" value="${database.pool.initialSize}"/>
          <property name="testOnReturn" value="true"/>
          <property name="validationQuery" value="select 1 from dual"/>
       </bean>
    
       <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
          <property name="dataSource" ref="dataSource"/>
       </bean>
    
       <bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
          <property name="dataSource" ref="dataSource"/>
       </bean>
    
       <bean class="org.springframework.transaction.support.TransactionTemplate" id="transactionTemplate">
          <property name="transactionManager" ref="transactionManager"/>
       </bean>
    
    </beans>

  • #2
    Do you have same beans defined in both application contexts?

    Comment


    • #3
      Originally posted by amiladomingo View Post
      Do you have same beans defined in both application contexts?
      No - the same beans are not defined in both contexts (applicationContext-barebones.xml is a subset of applicationContext-fullStack.xml).

      In the case where the issue pops up, we have unit tests which are configured to use applicationContext-fullStack.xml (but the autowiring appears to be only using beans in applicationContext-barebones.xml).

      Keep in mind the issue ONLY happens when you run all of the unit tests together, e.g. when we do something like
      Code:
      gradle test

      Comment


      • #4
        Hello,

        I think it's a matter of sequence. In my test-suites I always run tests with full application contexts prior to tests with reduced contexts.

        Hope this helps

        Jakob

        Comment

        Working...
        X