0 Replies Latest reply: Jan 12, 2012 11:07 PM by Adam Steffen RSS

JSFUnit and Tomcat 7

Adam Steffen Newbie

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