Announcement Announcement Module
Collapse
No announcement yet.
Unit testing with Spring Integration Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unit testing with Spring Integration

    Hi, I have a Spring MVC project and a fair bit of spring integration code that all work good when I deploy the war in my server.

    Now I want to write a few unit tests using testNG for my integration flows. When i execute the tests, I am getting

    java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.TestContext.getAp plicationContext(TestContext.java:157)
    ...
    Caused by: java.lang.IllegalStateException: Cannot load configuration class: org.springframework.web.servlet.config.annotation. DelegatingWebMvcConfiguration
    at org.springframework.context.annotation.Configurati onClassPostProcessor.enhanceConfigurationClasses(C onfigurationClassPostProcessor.java:366)
    ...


    Can you please point me to a Spring MVC project on GitHub that uses Spring Integration and have some JUnits/TestNG that works. I can refer to that and model my project.

    Thanks,
    Krish

  • #2
    Here is the stacktrace:

    org.springframework.beans.BeanInstantiationExcepti on: Could not instantiate bean class [org.springframework.test.context.web.WebDelegating SmartContextLoader]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: javax/servlet/ServletContext
    at org.springframework.beans.BeanUtils.instantiateCla ss(BeanUtils.java:163)
    at org.springframework.beans.BeanUtils.instantiateCla ss(BeanUtils.java:105)
    at org.springframework.beans.BeanUtils.instantiateCla ss(BeanUtils.java:130)
    at org.springframework.test.context.ContextLoaderUtil s.resolveContextLoader(ContextLoaderUtils.java:109 )
    at org.springframework.test.context.ContextLoaderUtil s.buildMergedContextConfiguration(ContextLoaderUti ls.java:362)
    at org.springframework.test.context.TestContext.<init >(TestContext.java:100)
    at org.springframework.test.context.TestContextManage r.<init>(TestContextManager.java:118)
    at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.createTestContextManager(SpringJUnit 4ClassRunner.java:119)
    at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.<init>(SpringJUnit4ClassRunner.java: 108)
    at sun.reflect.NativeConstructorAccessorImpl.newInsta nce0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInsta nce(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newI nstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Construc tor.java:513)
    at org.junit.internal.builders.AnnotatedBuilder.build Runner(AnnotatedBuilder.java:31)
    at org.junit.internal.builders.AnnotatedBuilder.runne rForClass(AnnotatedBuilder.java:24)
    at org.junit.runners.model.RunnerBuilder.safeRunnerFo rClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitie sBuilder.runnerForClass(AllDefaultPossibilitiesBui lder.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerFo rClass(RunnerBuilder.java:57)
    at org.junit.internal.requests.ClassRequest.getRunner (ClassRequest.java:24)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestR eference.<init>(JUnit4TestReference.java:33)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestC lassReference.<init>(JUnit4TestClassReference.java :25)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestL oader.createTest(JUnit4TestLoader.java:48)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestL oader.loadTests(JUnit4TestLoader.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRu nner.main(RemoteTestRunner.java:197)
    Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContext
    at org.springframework.test.context.web.WebDelegating SmartContextLoader.<init>(WebDelegatingSmartContex tLoader.java:36)
    at sun.reflect.NativeConstructorAccessorImpl.newInsta nce0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInsta nce(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newI nstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Construc tor.java:513)
    at org.springframework.beans.BeanUtils.instantiateCla ss(BeanUtils.java:148)
    ... 26 more
    Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext
    at java.net.URLClassLoader$1.run(URLClassLoader.java: 202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.j ava:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:3 06)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launche r.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:2 47)
    ... 32 more


    This is my JUnit test class:
    @ContextConfiguration
    @RunWith(SpringJUnit4ClassRunner.class)
    public class ComputerRequestGeneratorTests {

    @Autowired
    @Qualifier("computerRequestGeneratorInputChannel")
    QueueChannel computerRequestGeneratorInputChannel;

    @Autowired
    @Qualifier("computerInputChannel")
    QueueChannel computerInputChannel;

    @Autowired
    @Qualifier("testChannel")
    QueueChannel testChannel;

    @Test
    public void splitHappyFlow() {

    byte[] feederFile = null;
    try {
    feederFile = IOUtils.toByteArray(new FileInputStream(new File("ComputerRequestGenerator-1.txt")));
    }
    catch (IOException e) {
    Assert.assertTrue("Add testing file ComputerRequestGenerator-1.txt to the classpath.", true);
    return;
    }
    computerRequestGeneratorInputChannel.send(MessageB uilder.withPayload(feederFile).build());
    Message<?> outMessage1 = testChannel.receive(100);
    Assert.assertNotNull(outMessage1);
    Message<?> outMessage2 = testChannel.receive(100);
    Assert.assertNotNull(outMessage2);
    Message<?> outMessage3 = testChannel.receive(100);
    Assert.assertNotNull(outMessage3);

    }

    }

    Does Spring Test provide a way so that all the web beans gets mocked?

    Thanks.

    Comment


    • #3
      Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext
      You either need to isolate your code from dependencies on the Servlet APIs or you need to provide them on the classpath of your tests.

      Comment


      • #4
        Hi Gary,

        I also have the same error message:

        Could not instantiate bean class [org.springframework.test.context.web.WebDelegating SmartContextLoader]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: javax/servlet/ServletContext

        Can you elaborate on your previous reply ?

        How could I have a more explicit error message ?

        Thanks for any tip.

        I also have a post at http://forum.springsource.org/showth...678#post445678

        Kind Regards,
        Last edited by stephaneeybert; May 18th, 2013, 03:29 PM.

        Comment


        • #5
          Your unit tests either must not use the Servlet API or you need to provide it on the classpath.

          There's nothing more explicit than Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext

          The JDK can't load the class.

          Comment


          • #6
            I suggest you isolate your unit tests to just the POJO you create and not test the servlet or SI code, since those would be functional tests, perhaps handled best with a tool like JMeter. If you do want to unit test teh Spring INtegration flow through your POJO's, this can be done by creating a junit class which extends SingleRequestResponseScenarioTests.

            Then override the defineRequestResponseScenenario() method by setting up the entry point at an appropriate channel and returning the RequestResponseScenario it creates. I chose to use a response validator method, mainly so I could learn more and have a finer grain test.

            Code:
            @Override
                protected RequestResponseScenario defineRequestResponseScenario() {
                    String stringMessage = TestingUtils.buildStringFromFile("/test-messages/pingpong-good-request.xml");
                    MessageChannel replyChannel = applicationContext.getBean("outboundChannel", MessageChannel.class);
            
                    WFXMLSoapEnvelope soapEnvelope = buildSifHeader();
                    Message<String> message = MessageBuilder.withPayload(stringMessage)
                            .setReplyChannel(replyChannel)
                            .setHeader("testScenario", "scenarioInboundThruOutbound")
                            .setHeader(WS_HEADER_DATA, soapEnvelope.getHeader())
                            .build();
            
                    RequestResponseScenario scenario = new RequestResponseScenario("rawInboundChannel", "outboundChannel");
                    scenario.setMessage(message);
                    scenario.setResponseValidator(new MessageValidator() {
                        @Override
                        protected void validateMessage(Message<?> message) {
                            validateInboundThruOutbound(message);
                        }
                    });
                    return scenario;
                }
            I created the validateInboudThruOutbound() method while I was learning the Spring Integration processing, and choose to be detailed so I would catch any changes at the time I was making them.
            Code:
                /**
                 * validation for inbound scenario
                 * <p/>
                 * the "history=" header property contains the actual path the message traversed, 
                 * and is used to match what was the expected path.
                 *
                 * @param message
                 */
                private void validateInboundThruOutbound(Message<?> message) {
                    logger.debug("validateInboundThruOutbound:");
            
                    assertTrue(message.getPayload().toString().contains("Service is alive"));
                    assertThat(message, hasHeader("testScenario", "scenarioInboundThruOutbound"));
                    assertThat(message, hasPayload(is(String.class)));
            
                    String payloadAsString = (String) message.getPayload();
                    assertThat(payloadAsString, containsString("<keyword>22a4d2c50a0d236e01cd08883c496368</keyword>"));
            
                    MessageHistory mh = MessageHistory.read(message);
                    assertThat(mh.size(), is(equalTo(13)));
            
                    int index = 0;
                    Properties props = TestUtils.locateComponentInHistory(mh, "rawInboundChannel", index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "enrichWithTransactionId", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "ws-inboundChannel", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "enrichWithSoapHeader", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "enrichedWithSoapHeaderChannel", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "determineServiceRouter", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "pingPongChannel", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "pingPongServiceAuthenticator", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "secured.pingPongChannel", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "pingPongServiceActivator", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "pingPongResponseChannel", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "bridgePingPongToOutbound", ++index);
                    assertThat(props, is(notNullValue()));
            
                    props = TestUtils.locateComponentInHistory(mh, "outboundChannel", ++index);
                    assertThat(props, is(notNullValue()));
                }
            Last edited by Wrangler; May 22nd, 2013, 12:12 PM.

            Comment

            Working...
            X