Announcement Announcement Module
Collapse
No announcement yet.
AbstractDependencyInjectionSpringContextTests and Maven Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • AbstractDependencyInjectionSpringContextTests and Maven

    Does anyone experienced with AbstractDependencyInjectionSpringContextTests and Maven 2.0+? As you can see below the values from the applications context are loaded, but when the tests are executed the values are null.

    Thanks.

    INFO [16:15:52] (PropertiesLoaderSupport.java:loadProperties:168) - Loading properties file from class path resource [to
    m-test.properties]
    DEBUG [16:15:52] (PropertyPlaceholderConfigurer.javaarseStringValue:297) - Resolved placeholder 'test.url' to value [ht
    tp://localhost:8081]
    DEBUG [16:15:52] (CollectionFactory.java:createLinkedMapIfPossible: 114) - Creating [java.util.LinkedHashMap]
    INFO [16:15:52] (AbstractApplicationContext.java:initMessageSource :459) - Unable to locate MessageSource with name 'mess
    ageSource': using default [org.springframework.context.support.DelegatingMess ageSource@1e13d52]
    DEBUG [16:15:52] (CollectionFactory.java:createLinkedSetIfPossible: 90) - Creating [java.util.LinkedHashSet]
    INFO [16:15:52] (AbstractApplicationContext.java:initApplicationEv entMulticaster:481) - Unable to locate ApplicationEven
    tMulticaster with name 'applicationEventMulticaster': using default [org.springframework.context.event.SimpleApplicatio nE
    ventMulticaster@166aa18]
    DEBUG [16:15:52] (CollectionFactory.java:createLinkedMapIfPossible: 114) - Creating [java.util.LinkedHashMap]
    INFO [16:15:52] (DefaultListableBeanFactory.javareInstantiateSingletons:239) - Pre-instantiating singletons in factory
    [org.springframework.beans.factory.support.DefaultL istableBeanFactory defining beans [propertyConfigurer,asyncResponseTe
    st]; root of BeanFactory hierarchy]
    DEBUG [16:15:52] (AbstractBeanFactory.java:getBean:196) - Returning cached instance of singleton bean 'propertyConfigurer
    '
    DEBUG [16:15:52] (AbstractApplicationContext.javaublishEvent:232) - Publishing event in context [org.springframework.co
    ntext.support.ClassPathXmlApplicationContext;hashC ode=17682935]: org.springframework.context.event.ContextRefreshed Event[
    source=org.springframework.context.support.ClassPa thXmlApplicationContext: display name [org.springframework.context.supp
    ort.ClassPathXmlApplicationContext;hashCode=176829 35]; startup date [Fri Jul 28 16:15:51 CDT 2006]; root of context hiera
    rchy]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:150) - Getting BeanInfo for class [com.bea.core.tomcat.tests.htm
    lunit.AsyncResponseTest]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:166) - Caching PropertyDescriptors for class [com.bea.core.tomca
    t.tests.htmlunit.AsyncResponseTest]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:174) - Found property 'autowireMode' of type [int]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:174) - Found property 'class' of type [java.lang.Class]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:174) - Found property 'dependencyCheck' of type [boolean]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:174) - Found property 'loadCount' of type [int]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:174) - Found property 'name' of type [java.lang.String]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:174) - Found property 'populateProtectedVariables' of type [bool
    ean]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:174) - Found property 'testMainServletName' of type [java.lang.S
    tring]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:174) - Found property 'testTimeoutServletName' of type [java.lan
    g.String]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:<init>:174) - Found property 'testUrl' of type [java.lang.String]
    DEBUG [16:15:52] (CachedIntrospectionResults.java:forClass:92) - Class [com.bea.core.tomcat.tests.htmlunit.AsyncResponseT
    est] is cache-safe
    INFO [16:15:52] (AsyncResponseTest.java:testAsyncResponse:40) - Testing regular asynchronous response
    INFO [16:15:52] (AsyncResponseTest.java:testAsyncResponse:42) - Test url: null/null
    INFO [16:15:52] (AbstractTomTest.java:getConfigLocations:26) - Setting configuration locations.
    DEBUG [16:15:52] (CachedIntrospectionResults.java:forClass:103) - Using cached introspection results for class [com.bea.c
    ore.tomcat.tests.htmlunit.AsyncResponseTest]
    INFO [16:15:52] (AsyncResponseTest.java:testAsyncResponseTimeout:4 9) - Testing asynchronous response timeout
    INFO [16:15:52] (AsyncResponseTest.java:testAsyncResponseTimeout:5 1) - Test url: null/null
    Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 0.968 sec <<< FAILURE!

  • #2
    What does your test actually do - it might be that an URL (used to load a resource for example) is not found if the test is ran inside maven classloader which might be properly setup.
    AbstractDISCT is just a junit test - try to load the url/properties manually and see if that makes a difference.

    Comment


    • #3
      JUnit is able to see the the resources - properties file and application-context (applicationContext-tom.xml). Spring is also finding the test bean - "asyncResponseTest". The test simply uses values from Spring to create a URL which HTMLUnit tests.

      // set Spring context location
      protected String[] getConfigLocations() {
      logger.info("Setting configuration locations.");
      return new String[] {
      "classpath:applicationContext-tom.xml"};
      }

      // load Spring context
      protected ConfigurableApplicationContext loadContextLocations(
      String[] locations) {
      logger.info("Loading configurations.");
      ConfigurableApplicationContext appCntxt = null;
      try {
      appCntxt = new ClassPathXmlApplicationContext(locations);
      } catch (BeansException e) {
      e.printStackTrace();
      }
      return appCntxt;
      }


      INFO [20:25:26] (AbstractRefreshableApplicationContext.java:refres hBeanFactory:92) - Bean factory for application contex
      t [org.springframework.context.support.ClassPathXmlAp plicationContext;hashCode=25657668]: org.springframework.beans.facto
      ry.support.DefaultListableBeanFactory defining beans [propertyConfigurer,asyncResponseTest]; root of BeanFactory hierarch
      y
      INFO [20:25:27] (AbstractApplicationContext.java:refresh:307) - 2 beans defined in application context [org.springframew
      ork.context.support.ClassPathXmlApplicationContext ;hashCode=25657668]
      DEBUG [20:25:27] (AbstractBeanFactory.java:getBean:237) - Creating shared instance of singleton bean 'propertyConfigurer'

      DEBUG [20:25:27] (AbstractAutowireCapableBeanFactory.java:createBea n:343) - Creating instance of bean 'propertyConfigurer
      ' with merged definition [Root bean: class [org.springframework.beans.factory.config.PropertyP laceholderConfigurer]; abst
      ract=false; singleton=true; lazyInit=false; autowire=0; dependencyCheck=0; factoryBeanName=null; factoryMethodName=null;
      initMethodName=-; destroyMethodName=-; defined in class path resource [applicationContext-tom.xml]]


      <?xml version="1.0" encoding="UTF-8"?>

      <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd">

      <!-- loads properties from pool-test.properties -->
      <bean id="propertyConfigurer"
      class="org.springframework.beans.factory.config.Pr opertyPlaceholderConfigurer">
      <property name="locations">
      <list>
      <value>classpath:tom-test.properties</value>
      </list>
      </property>
      </bean>

      <!-- async response test -->
      <bean id="asyncResponseTest"
      class="test.AsyncResponseTest"
      singleton="false">
      <property name="testUrl" value="${test.url}"/>
      <property name="mainTestName" value="async-main-test"/>
      <property name="timeoutTesttName" value="async-timeout-test"/>
      </bean>

      </beans>

      Comment


      • #4
        If I understand correctly the problem lies here:
        classpath:tom-test.properties
        this being the resource which has to be properly resolved in order to replace the property keys with their actual values. make sure that you can properties file can be read from the classpath - i.e. inside your JUnit do something like
        getClass().getClassLoader().getResource("tom-test.properties");
        and make sure that the resource is not null. This way you can verify that the classpath is properly set.
        If this works and testUrl is still not injected then make sure test.url is inside the found properties.

        Comment


        • #5
          Hi Costin.

          I eliminated the PropertyPlaceholderConfigurer usage to narrow down the issue. Even w/o PropertyPlaceholderConfigurer properties are not being injected.

          What's confusing is that when I created an arbitrary bean to simply hold a to-be-injected String, the bean is injected properly.

          <!-- async response test -->
          <bean id="asyncResponseTest"
          class="com.bea.core.tomcat.tests.htmlunit.AsyncRes ponseTest">
          <property name="testBean" ref="testBean"/>
          <property name="mainTestName" value="chris-async-main-test"/>
          <property name="timeoutTestName" value="chris-async-timeout-test"/>
          </bean>

          <bean id="testBean" class="com.bea.core.tomcat.tests.htmlunit.TestBean ">
          <property name="testUrl" value="http://localhost:9999/testTomWebapp"/>
          </bean>

          I wonder how others have used AbstractDISCT via Maven. Certainly I can't be the only one. My usecase is very basic.

          -Chris

          Comment


          • #6
            I just noticed that inside your test you are instantiating Spring application context - you shouldn't do that.
            Simply add the tests to your junit - the purpose of the AbstractDISCT is to inject the properties into the test as well as cache the Spring application context between several reruns so you don't have to instantiate one for every test.

            Comment


            • #7
              Gotcha. I removed loadContextLocations(). Unfortunately I'm still stuck at injecting string properties. Is there any additional information I can provide?

              <bean id="asyncResponseTest"
              class="com.bea.core.tomcat.tests.htmlunit.AsyncRes ponseTest">
              <!-- the following ref works -->
              <property name="testBean" ref="testBean"/>
              <!-- this does not work -->
              <property name="mainTestName" value="this-should-be-injected"/>
              </bean>

              INFO [14:13:04] (AsyncResponseTest.java:setMainTestName:33) - Setting mainTestName=this-should-be-injected
              INFO [14:13:04] (AsyncResponseTest.java:testAsyncResponse:39) - ### A S Y N C R E S P O N S E - M A I N ###
              INFO [14:13:04] (AsyncResponseTest.java:testAsyncResponse:42) - Getting url: http://localhost:8081/testTomWebapp/null

              Comment


              • #8
                You should not even define your test inside the application context - the idea is that test used business components and by default the abstactDISCT will use autowire to the components from the application context and inject them into the test.

                So remove the test, specify what context to be used inside getLocation (you are already doing that) and simply create setters for the components you want to be injected inside your junit.
                Note that you also have a protected applicationContext field which you can use to do lookups.

                So if you want to inject an url, all you'd had to do was:

                public class MyTest extends Abstract... {

                private URL url;

                public void setUrl(URL someUrl) {
                this.url = someUrl;
                }

                protected String[] getConfigLocations() {..}
                public void testUrl() {
                assertNotNull(someUrl);
                }
                }
                I hope that's a bit clearer now - take a look at the javadoc and the reference documentation. Also try searching the forum - you'll find several threads including examples on who you can use the test suite.

                Comment


                • #9
                  That's exactly what I'm doing...

                  public class AsyncResponseTest
                  extends TomTestBase {

                  public String mainTestName = "async-main-test";
                  public String timeoutTestName = "async-timeout-test";

                  public String getTimeoutTestName() {
                  return timeoutTestName;
                  }

                  public void setTimeoutTestName(String timeoutTestName) {
                  logger.info("Setting timeoutTestName="+timeoutTestName);
                  this.timeoutTestName = timeoutTestName;
                  }

                  public String getMainTestName() {
                  return mainTestName;
                  }

                  public void setMainTestName(String mainTestName) {
                  logger.info("Setting mainTestName="+mainTestName);
                  this.mainTestName = mainTestName;
                  }

                  // tests
                  public void testAsyncResponse() throws Exception {
                  logger.info("### A S Y N C R E S P O N S E - M A I N ###");
                  ...
                  }
                  }


                  public class TomTestBase
                  extends AbstractDependencyInjectionSpringContextTests {

                  public TestBean testBean;

                  public TestBean getTestBean() {
                  return testBean;
                  }

                  public void setTestBean(TestBean testBean) {
                  this.testBean = testBean;
                  }

                  // set Spring context location
                  protected String[] getConfigLocations() {
                  logger.info("Setting configuration locations.");
                  return new String[] {
                  "classpath:applicationContext-tom.xml"};
                  }

                  protected String getTestUrl() {
                  return testBean.getTestUrl();
                  }
                  ...
                  }

                  Like I said, Strings are not being injected into my test class. TestBean is being injected.

                  <bean id="asyncResponseTest"
                  class="com.bea.core.tomcat.tests.htmlunit.AsyncRes ponseTest">
                  <!-- the following ref works -->
                  <property name="testBean" ref="testBean"/>
                  <!-- this does not work -->
                  <property name="mainTestName" value="this-should-be-injected"/>
                  </bean>

                  Comment


                  • #10
                    Remove the Test definition from your application-context, you (at least I never do) define your testcases in a applicationContext.xml file.

                    Code:
                    <bean name="mainTestName" class="java.lang.String">
                        <constructor-arg index="0">
                            <value>this-should-be-injected</value>
                        </constructor-arg>
                    </bean>
                    URL-example:
                    Code:
                    <bean name="testUrl" class="java.net.URL">
                        <constructor-arg index="0">
                            <value>http://whatever.domain.org/testurl</value>
                        </constructor-arg>
                    </bean>
                    The TestBean is getting injected into your testcase because of the autowiring capability not because of your testcase definition in your applicationcontext.xml.

                    If you would create a test method which retrieves the bean with the name "asyncResponseTest" yuo probably would see a instance registered with al the properties set as you decided. The testcase you are running and the testcase defined in the applicationContext.xml are 2 different instances of the same class.

                    Comment

                    Working...
                    X