0 Replies Latest reply on Jan 12, 2012 11:07 PM by atsteffen

    JSFUnit and Tomcat 7

    atsteffen

      Hi All,

       

      I'm thrilled to get some CDI unit tests running for my Tomcat 7 web app.  But i've had mixed luck so far.  I'm wondering how well others have fared using JSFUnit 2.0/Arquillian with Tomcat 7.  I'm somewhat invested in using tomcat 7 for my application, but I'm not sure I can live without unit tests for my CDI beans and such.  Do you all think this the best route (jsfunit) right now for adding integration testing to my project? I realize things are still in development.  In any case I thought I would put down what I've done so far, and hopefully get some help refining it to a working example.

       

      Here's a test project layout:

      Screen Shot 2012-01-12 at 7.11.37 PM.png

       

      HelloJSFTest.java:

      @RunWith(Arquillian.class)
      public class HelloJSFTest
      {
         @Deployment
         public static WebArchive createDeployment() {
            WebArchive war =
               ShrinkWrap.create(WebArchive.class, "test.war")
                  .setWebXML(new File("src/main/webapp/WEB-INF/web.xml"))
                  .addClass(MyBean.class)
                  .addAsWebResource(new File("src/main/webapp", "index.xhtml"))
                  .addAsManifestResource("context.xml", "context.xml")
                  .addAsWebInfResource(new File("src/main/webapp/WEB-INF/faces-config.xml"), "faces-config.xml")
                  .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
            //System.out.println(war.toString(true)); // for debugging
            return war;
         }
      
          @Inject MyBean userbean;
          @Test
          public void testUserBeanInjection() {
                Assert.assertNotNull(userbean);
          }
      
          @Test
          public void beanHasAccessToClassDependencies() {
                Assert.assertFalse(userbean.isLoggedIn());
          }
      
         @Test
         @InitialPage("/index.faces")
         public void testInitialPage(JSFServerSession server, JSFClientSession client) throws IOException
         {
            // Test navigation to initial viewID
             Assert.assertEquals("/index.xhtml", server.getCurrentViewID());
      
             // Set the param and submit
             client.setValue("name", "Stan");
             client.click("submit_button");
      
             // Assert that the greeting component is in the component tree and rendered
             UIComponent greeting = server.findComponent("greeting");
             Assert.assertTrue(greeting.isRendered());
      
             // Test a managed bean using EL. We cheat and use the request object.
             Assert.assertEquals("Stan", server.getManagedBeanValue("#{request.getParameter('form1:name')}"));
         }
      }
      

       

      arquillian.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian-1.0.xsd">
      
          <engine>
              <property name="deploymentExportPath">target/</property>
          </engine>
      
          <container qualifier="tomcat" default="true">
              <configuration>
                  <property name="bindHttpPort">8888</property>
                  <property name="unpackArchive">true</property>
                  <property name="user">tomcat</property>
                  <property name="pass">tomcat</property>
              </configuration>
          </container>
      
        <defaultProtocol type="Servlet 3.0" />
      
      </arquillian>
      

       

      context.xml:

      <?xml version="1.0" encoding="UTF-8"?>
      <Context>
        <Resource name="BeanManager" 
        auth="Container"
        type="javax.enterprise.inject.spi.BeanManager"
        factory="org.jboss.weld.resources.ManagerObjectFactory"/>
      </Context>
      

       

      web.xml:

      <?xml version="1.0"?>
      <web-app xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
          version="3.0">
      
        <listener>
           <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
        </listener>
      
        <servlet>
          <servlet-name>Faces Servlet</servlet-name>
          <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
          <load-on-startup>1</load-on-startup>
        </servlet>
      
        <servlet-mapping>
          <servlet-name>Faces Servlet</servlet-name>
          <url-pattern>*.faces</url-pattern>
        </servlet-mapping>
      
        <welcome-file-list>
          <welcome-file>index.html</welcome-file>
        </welcome-file-list>  
      
        <filter>
            <filter-name>JSFUnitCleanupTestTreadFilter</filter-name>
            <filter-class>org.jboss.jsfunit.arquillian.container.JSFUnitCleanupTestTreadFilter</filter-class>
          </filter>
      
          <filter>
            <filter-name>JSFUnitFilter</filter-name>
            <filter-class>org.jboss.jsfunit.framework.JSFUnitFilter</filter-class>
          </filter>
      
          <filter-mapping>
            <filter-name>JSFUnitCleanupTestTreadFilter</filter-name>
            <url-pattern>/ArquillianServletRunner</url-pattern>
          </filter-mapping>    
      
          <filter-mapping>
            <filter-name>JSFUnitFilter</filter-name>
            <url-pattern>/ArquillianServletRunner</url-pattern>
          </filter-mapping>
      
      </web-app>
      

       

      pom.xml:

       

      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      
        <modelVersion>4.0.0</modelVersion>
      
        <groupId>org.jboss.jsfunit</groupId>
        <artifactId>gettingstarted</artifactId>
        <version>2.0.0.Beta2</version>
        <packaging>war</packaging>
        <name>Minimal example for the Getting Started Guide</name>
      
        <repositories>
        <repository>
        <id>jboss-public-repository-group</id>
        <name>JBoss Public Maven Repository Group</name>
        <url>http://repository.jboss.org/nexus/content/groups/public</url>
        <layout>default</layout>
        <releases>
        <enabled>true</enabled>
        <updatePolicy>never</updatePolicy>
        </releases>
        <snapshots>
        <enabled>false</enabled>
        <updatePolicy>never</updatePolicy>
        </snapshots>
        </repository>
        </repositories>
        <pluginRepositories>
        <pluginRepository>
        <id>jboss-public-repository-group</id>
        <name>JBoss Public Maven Repository Group</name>
        <url>http://repository.jboss.org/nexus/content/groups/public</url>
        <layout>default</layout>
        <releases>
        <enabled>true</enabled>
        <updatePolicy>never</updatePolicy>
        </releases>
        <snapshots>
        <enabled>true</enabled>
        <updatePolicy>never</updatePolicy>
        </snapshots>
        </pluginRepository>
        </pluginRepositories>
      
        <properties>
        <version.jsfunit>2.0.0.Beta2</version.jsfunit>
        <version.arquillian>1.0.0.CR4</version.arquillian>
        <version.shrinkwrap>1.0.0-beta-5</version.shrinkwrap>
        <version.shrinkwrap.descriptors>1.1.0-alpha-2</version.shrinkwrap.descriptors>
        <version.org.apache.tomcat>7.0.22</version.org.apache.tomcat>
        </properties>
      
        <dependencies>
      
        <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.2</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
        <groupId>org.jboss.arquillian.junit</groupId>
        <artifactId>arquillian-junit-container</artifactId>
        <version>${version.arquillian}</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
        <groupId>org.jboss.arquillian.protocol</groupId>
        <artifactId>arquillian-protocol-servlet</artifactId>
        <version>${version.arquillian}</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
        <groupId>org.jboss.arquillian.container</groupId>
        <artifactId>arquillian-container-spi</artifactId>
        <version>${version.arquillian}</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
        <groupId>org.jboss.jsfunit</groupId>
        <artifactId>jsfunit-arquillian</artifactId>
        <version>${version.jsfunit}</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
        <groupId>org.jboss.jsfunit</groupId>
        <artifactId>jboss-jsfunit-core</artifactId>
        <version>${version.jsfunit}</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
        <groupId>org.jboss.shrinkwrap.descriptors</groupId>
        <artifactId>shrinkwrap-descriptors-impl</artifactId>
        <version>${version.shrinkwrap.descriptors}</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
        <groupId>org.jboss.shrinkwrap.resolver</groupId>
        <artifactId>shrinkwrap-resolver-api-maven</artifactId>
        <version>${version.shrinkwrap}</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
        <groupId>org.jboss.shrinkwrap.resolver</groupId>
        <artifactId>shrinkwrap-resolver-impl-maven</artifactId>
        <version>${version.shrinkwrap}</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
        <groupId>javax.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <version>2.0</version>
        </dependency>
      
        <dependency>
        <groupId>javax.faces</groupId>
        <artifactId>jsf-impl</artifactId>
        <version>2.0.2-FCS</version>
        </dependency>
      
        </dependencies>
      
        <profiles>
      
        <profile>
           <id>tomcat-embedded</id>
        <dependencies>
        <dependency>
           <groupId>org.jboss.arquillian.container</groupId>
           <artifactId>arquillian-tomcat-embedded-7</artifactId>
           <version>1.0.0.CR2</version>
        <scope>test</scope>
        </dependency>
      
        <dependency>
           <groupId>org.apache.tomcat</groupId>
           <artifactId>tomcat-catalina</artifactId>
           <version>${version.org.apache.tomcat}</version>
        <scope>test</scope>
        </dependency>
        <dependency>
           <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-coyote</artifactId>
           <version>${version.org.apache.tomcat}</version>
           <scope>provided</scope>
        </dependency>
        <dependency>
           <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-jasper</artifactId>
           <version>${version.org.apache.tomcat}</version>
           <scope>provided</scope>
        </dependency>
        <!-- Weld servlet, EL and JSP required for testing CDI injections -->
        <dependency>
           <groupId>org.jboss.weld.servlet</groupId>
        <artifactId>weld-servlet</artifactId>
           <version>1.0.1-Final</version>
        <scope>test</scope>
        </dependency>
        </dependencies>
        </profile>
        </profiles>
      </project>
      
      

       

      I followed the advice of @hettothecool in this discussion: https://community.jboss.org/wiki/JSFUnit20AndTomcat6.  Using this pom.xml, web.xml and arquillian.xml plus some modifications I get things mostly running.  Oddly enough my tests only run successfully in eclipse.  When I try to run my test using "mvn -Ptomcat-embedded test", I get errors:

      java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
           at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:804)
           at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:306)
           at javax.faces.webapp.FacesServlet.init(FacesServlet.java:166)
           at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1228)
           at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1147)
           ....
      

       

      I've attached the sunfire report for this error which gives:

       

      java.lang.RuntimeException: Could not inject method parameters
              at org.jboss.jsfunit.arquillian.container.JSFUnitTestEnricher.resolve(JSFUnitTestEnricher.java:89)
              at org.jboss.arquillian.container.test.impl.execution.LocalTestExecuter.enrichArguments(LocalTestExecuter.java:94)
              .....
      

       

      I find it really odd that importing a project to eclipse leads to a successful run, while using the terminal does not.  Any help with this specific issue or pointers to add to my test project would be appreciated.

       

      Adam