2 Replies Latest reply on Jan 7, 2014 3:35 PM by kokovoj

    Injecting Spring MVC Controller from .war included in the .ear into Arquillian test

    kokovoj

      I have a large .ear that consists of multiple .jars and multiple .war files that I am deploying into JBoss. I want to do end-to-end testing on one of the .wars' Controllers using spring-test-mvc framework, and hence need mvc Controllers from that .war @Autowired into my Arquillium test class. The .war in question has a servlet named "myservlet" in its web.xml (<servlet-name>myservlet</servlet-name>, and that's what I am using in SpringWebConfiguration below. The .ear (including the .war that I need to test) gets successfully deployed to JBoss, however, the Controller class is never injected and hence remains null.

      I am using arquillian-jbossas-managed-4.2.

       

      My test class looks like this :

       

      @SpringWebConfiguration(servletName = "myservlet")

      @RunWith(Arquillian.class)

      public class AqruilliumTest {

       

         @Autowired

          private MyController myController;

       

         @Deployment

          public static Archive createDeployment() {

                // Create an Archive from the existing .ear build on the file system (not manually constructed in this method)

                EnterpriseArchive ear = ShrinkWrap

                  .create( ZipImporter.class, "myLarge.ear" )

                  .importFrom( new File( "/Users/kokovoj/EarAndItsVariousComponents/An-Overall-EAR-folder/myLarge.ear" ) )

                  .as( EnterpriseArchive.class );

              System.out.println( ear.toString( true ) );

              return ear;

          }

       

          @Test

          @RunAsClient

          public void controllerInjected() throws Exception {

              System.out.println( "--->>myController [" + myController + "]" );

              assertNotNull( myController );

          }

       

      Questions :

       

      1. Is there a requirement / assumption that when using @SpringWebConfiguration, @Deployment public static Archive createDeployment() method MUST return a WebArchive for spring injections to work ? I am returning an EnterpriseArchive so is that the reason it does NOT work for me; is there a workaround for making this work for .ear ?

       

      2. In @Deployment public static Archive createDeployment() method I am not constructing the .ear manually, but rather using an existing .ear on the file system. Is there a requirement / assumption that archive must be constructed manually through code (and not use an existing archive from the file system) for spring injections to work ?

        • 1. Re: Injecting Spring MVC Controller from .war included in the .ear into Arquillian test
          jmnarloch

          Hi,

           

          Sorry for late replay.

           

          I admit that I didn't test such solution, but as far as I'm concerned the only requirement for the usage of @SpringWebConfiguration is to configure the ContextLoaderListener. You do not need to define your beans in it's scope, but it is mandatary for the integration to work correctly, without it the extension is not being able to access the ApplicationContext of the particular DispatcherServlet.

           

          <listener>
            
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>

           

          If it happens that you were using it in your application and nevertheless the test didn't work, would mind raising a JIRA (issues.jboss.org/browse/ARQ) issue for that?

          • 2. Re: Injecting Spring MVC Controller from .war included in the .ear into Arquillian test
            kokovoj

            Finally had time to go back to this issue.

             

            The issue is solved (ie. largeController correctly injected into my test class, and not being null) by explicitly adding the test class itself into the .war included in the .ear. This works for both managed and embedded container types (I got it working with JBoss AS 4.2, JBoss AS 6.0). This is done by using below code

             

            @RunWith(Arquillian.class)

            @SpringWebConfiguration(servletName = "myservlet")

            public class Test_JBoss_Managed_4_2_3

             

               @Autowired

               private LargeController largeController;

             

               @OverProtocol( "Servlet 2.5" )

               @Deployment

                public static EnterpriseArchive createDeployment() {

                      // Create an Archive from the existing .ear build on the file system (not manually constructed in this method)

                      EnterpriseArchive ear = ShrinkWrap

                        .create( ZipImporter.class, "myLarge.ear" )

                        .importFrom( new File( "/Users/kokovoj/EarAndItsVariousComponents/An-Overall-EAR-folder/myLarge.ear" ) )

                        .as( EnterpriseArchive.class );

                    System.out.println( ear.toString( true ) );

             

                    // CRITICAL: For .ear deployments (ie. when this method returns EnterpriseArchive which gets deployed to JBoss)

                    // need to explicitly add this test class (ie. Test_JBoss_Managed_4_2_3) into the deployed artifact (ie. .war)

                    // so that it's visible during deployment.

                    WebArchive web = ear.getAsType( WebArchive.class, "myLarge-web.war" );

                    // Add this class (Test_JBoss_Managed_4_2_3) so that it will be included as part of the deployed .war (inside of an .ear).

                    web.addClasses(Test_JBoss_Managed_4_2_3.class );

             

                    return ear;

               }

             

                @Test

                public void testControllerInjected() throws Exception {

                    assertNotNull( "largeController is invalid", largeController );

                }