JSFUnit and Tomcat 7
atsteffen Jan 12, 2012 11:07 PMHi 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:
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
