SeamTest and UnitDBSeamTest configuration issue - doesn't work out of the box
themathmagician Mar 12, 2009 1:28 PMI have spent quite some time trying to figure out how to run unit/integration tests using Seam.
I have looked for this information in the Seam Documentation, and also the books Seam in Action, and Seam Evolution.
The examples in the documention do not work out of the box, if you use them on a seam-gen project.
There have been many posts here on this forum regarding running the seam integration tests...
I see that these tests are working for the example projects, but because the buildfile is SO different from the one generated by seam-gen, I haven't been able to figure out what the trick is. (Apparently, the example projects when tested don't have a persitence.xml file at all?)
Digging trough this forum, and seeing how many people had problems with running tests, I thought it might be helpful to create a "Test example" project, which has the same structure as a typical seam-gen project, and demonstrates the various options for testing.
Hope you guys can help me in finding out, which magical combination of datasource, persitence.xml settings etc does the trick!
+++ Here are my steps:
I genereated a new project using seam-gen.
I used the seam-gen new-entity and new-action to create the entity User, the view user.xhtml and the action class UserBean.
I didn't change the configuration of the project.
+++ I have made 3 test-types:
# Integration test - made by seam-gen - this one is working.
`
new FacesRequest() {
@Override
protected void invokeApplication() {
invokeMethod("#{user.user}");
}
}.run();
}
`
This test is passing!
# A test that uses the facelet name in the contructor of FacesRequest
`
@Test
public void test_user_ui_with_facelet_param_in_constructor() throws Exception {
new FacesRequest("/user.xhtml") {
@Override
protected void updateModelValues() throws Exception {
// Bind simulated user input data objects
// to Seam components
assert getFacesContext().getViewRoot() != null;
}
@Override
protected void invokeApplication() {
// Invoke the UI event handler method for
// the HTTP POST button or link
}
@Override
protected void renderResponse() {
// Retrieve and test the response
// data objects
}
}.run();
}
}`
This test is failing, see the stack trace below ...
# A test that extends UnitDBSeamTest
`public class UnitDBPersistenceTest extends DBUnitSeamTest {
protected EntityManager em;
@BeforeTest
public void init(){
//EntityManagerFactory emf = Persistence.createEntityManagerFactory("run");
//em = emf.createEntityManager();
}
@AfterTest
public void close(){
em.close();
}
@Test
public void test_user_crud_using_unitdb(){
User user = new User();
}
@Override
protected void prepareDBUnitOperations() {
beforeTestOperations.add(new DataSetOperation("cruddataset.xml"));
}
}`
This test if failing, see the stacktrace below.
The cruddataset is very simple:
`<dataset>
<USER
id="1"
name="hans"
version="1"
/>
</dataset>
`
+++Stacktrace
Here is the stack trace of the failing tests:
` [testng] FAILED CONFIGURATION: @BeforeClass setupClass
[testng] java.lang.RuntimeException: org.dbunit.dataset.DataSetException: java.net.MalformedURLException
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest$DataSetOperation.<init>(AbstractDBUnitSeamTest.java:235)
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest$DataSetOperation.<init>(AbstractDBUnitSeamTest.java:250)
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest$DataSetOperation.<init>(AbstractDBUnitSeamTest.java:200)
[testng] at dk.mathmagicians.runtest.test.UnitDBPersistenceTest.prepareDBUnitOperations(UnitDBPersistenceTest.java:37)
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest.setupClass(AbstractDBUnitSeamTest.java:142)
[testng] at org.jboss.seam.mock.DBUnitSeamTest.setupClass(DBUnitSeamTest.java:42)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[testng] at java.lang.Thread.run(Thread.java:619)
[testng] Caused by: org.dbunit.dataset.DataSetException: java.net.MalformedURLException
[testng] at org.dbunit.dataset.xml.FlatXmlProducer.produce(FlatXmlProducer.java:169)
[testng] at org.dbunit.dataset.CachedDataSet.<init>(CachedDataSet.java:71)
[testng] at org.dbunit.dataset.xml.FlatXmlDataSet.<init>(FlatXmlDataSet.java:200)
[testng] at org.dbunit.dataset.xml.FlatXmlDataSet.<init>(FlatXmlDataSet.java:187)
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest$DataSetOperation.<init>(AbstractDBUnitSeamTest.java:226)
[testng] ... 19 more
[testng] ... Removed 11 stack frames
[testng] FAILED CONFIGURATION: @AfterMethod end
[testng] java.lang.NullPointerException
[testng] at org.jboss.seam.servlet.ServletSessionMap.get(ServletSessionMap.java:54)
[testng] at org.jboss.seam.contexts.BasicContext.get(BasicContext.java:49)
[testng] at org.jboss.seam.Component.getInstance(Component.java:1926)
[testng] at org.jboss.seam.Component.getInstance(Component.java:1921)
[testng] at org.jboss.seam.Component.getInstance(Component.java:1894)
[testng] at org.jboss.seam.Component.getInstance(Component.java:1889)
[testng] at org.jboss.seam.core.ConversationEntries.instance(ConversationEntries.java:94)
[testng] at org.jboss.seam.contexts.Lifecycle.endSession(Lifecycle.java:236)
[testng] at org.jboss.seam.contexts.ServletLifecycle.endSession(ServletLifecycle.java:146)
[testng] at org.jboss.seam.mock.AbstractSeamTest.end(AbstractSeamTest.java:904)
[testng] at org.jboss.seam.mock.SeamTest.end(SeamTest.java:37)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[testng] at java.lang.Thread.run(Thread.java:619)
[testng] ... Removed 13 stack frames
[testng] SKIPPED CONFIGURATION: @BeforeClass setDatasourceJndiName
[testng] SKIPPED CONFIGURATION: @BeforeMethod begin
[testng] SKIPPED CONFIGURATION: @AfterMethod end
[testng] SKIPPED CONFIGURATION: @AfterClass cleanupClass
[testng] SKIPPED CONFIGURATION: @AfterClass cleanupClass
[testng] SKIPPED CONFIGURATION: @AfterTest close
[testng] PASSED: test_user_with_noarg_facesrequest_constructor
[testng] PASSED: unitTestCrudUsingEntityHome
[testng] FAILED: test_using_seamtest_and_entitymanager
[testng] java.lang.AssertionError
[testng] at dk.mathmagicians.runtest.test.EntityManagerPersistenceTest.test_using_seamtest_and_entitymanager(EntityManagerPersistenceTest.java:26)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[testng] at java.lang.Thread.run(Thread.java:619)
[testng] ... Removed 11 stack frames
[testng] SKIPPED: test_user_crud_using_unitdb
[testng] ===============================================
[testng] Various Tests
[testng] Tests run: 4, Failures: 1, Skips: 1
[testng] Configuration Failures: 2, Skips: 6
[testng] ===============================================
`
+++ My configuration
The TestNG suite:
`
suite name="TestingTestFramework" verbose="2" parallel="true">
<parameter name="datasourceJndiName" value="java:/runtestDatasource" />
<parameter name="database" value="HSQL" />
<parameter name="binaryDir" value="" />
<test name="Various Tests">
<classes>
<class name="dk.mathmagicians.runtest.test.UnitDBPersistenceTest" />
<class name="dk.mathmagicians.runtest.test.EntityManagerPersistenceTest" />
<class name="dk.mathmagicians.runtest.test.UserTest" />
<class name="dk.mathmagicians.runtest.test.UserUiTest" />
</classes>
</test>
</suite>
`
The persitence-test.xml - I tried some of the advices from forum, but no success ...
`
<persistence-unit name="runtest" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.cache.use_second_level_cache"
value="false" />
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/runtestEntityManagerFactory" />
<property name="hibernate.transaction.flush_before_completion"
value="true" />
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup" />
</properties>
</persistence-unit>
</persistence>
`
The User, UserBean and user.xhtml are trivial, autogenerated by seam.
Its clearly a configuration issue - can anybody help out?
Agata
I have looked for this information in the Seam Documentation, and also the books Seam in Action, and Seam Evolution.
The examples in the documention do not work out of the box, if you use them on a seam-gen project.
There have been many posts here on this forum regarding running the seam integration tests...
I see that these tests are working for the example projects, but because the buildfile is SO different from the one generated by seam-gen, I haven't been able to figure out what the trick is. (Apparently, the example projects when tested don't have a persitence.xml file at all?)
Digging trough this forum, and seeing how many people had problems with running tests, I thought it might be helpful to create a "Test example" project, which has the same structure as a typical seam-gen project, and demonstrates the various options for testing.
Hope you guys can help me in finding out, which magical combination of datasource, persitence.xml settings etc does the trick!
+++ Here are my steps:
I genereated a new project using seam-gen.
I used the seam-gen new-entity and new-action to create the entity User, the view user.xhtml and the action class UserBean.
I didn't change the configuration of the project.
+++ I have made 3 test-types:
# Integration test - made by seam-gen - this one is working.
`
new FacesRequest() {
@Override
protected void invokeApplication() {
invokeMethod("#{user.user}");
}
}.run();
}
`
This test is passing!
# A test that uses the facelet name in the contructor of FacesRequest
`
@Test
public void test_user_ui_with_facelet_param_in_constructor() throws Exception {
new FacesRequest("/user.xhtml") {
@Override
protected void updateModelValues() throws Exception {
// Bind simulated user input data objects
// to Seam components
assert getFacesContext().getViewRoot() != null;
}
@Override
protected void invokeApplication() {
// Invoke the UI event handler method for
// the HTTP POST button or link
}
@Override
protected void renderResponse() {
// Retrieve and test the response
// data objects
}
}.run();
}
}`
This test is failing, see the stack trace below ...
# A test that extends UnitDBSeamTest
`public class UnitDBPersistenceTest extends DBUnitSeamTest {
protected EntityManager em;
@BeforeTest
public void init(){
//EntityManagerFactory emf = Persistence.createEntityManagerFactory("run");
//em = emf.createEntityManager();
}
@AfterTest
public void close(){
em.close();
}
@Test
public void test_user_crud_using_unitdb(){
User user = new User();
}
@Override
protected void prepareDBUnitOperations() {
beforeTestOperations.add(new DataSetOperation("cruddataset.xml"));
}
}`
This test if failing, see the stacktrace below.
The cruddataset is very simple:
`<dataset>
<USER
id="1"
name="hans"
version="1"
/>
</dataset>
`
+++Stacktrace
Here is the stack trace of the failing tests:
` [testng] FAILED CONFIGURATION: @BeforeClass setupClass
[testng] java.lang.RuntimeException: org.dbunit.dataset.DataSetException: java.net.MalformedURLException
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest$DataSetOperation.<init>(AbstractDBUnitSeamTest.java:235)
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest$DataSetOperation.<init>(AbstractDBUnitSeamTest.java:250)
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest$DataSetOperation.<init>(AbstractDBUnitSeamTest.java:200)
[testng] at dk.mathmagicians.runtest.test.UnitDBPersistenceTest.prepareDBUnitOperations(UnitDBPersistenceTest.java:37)
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest.setupClass(AbstractDBUnitSeamTest.java:142)
[testng] at org.jboss.seam.mock.DBUnitSeamTest.setupClass(DBUnitSeamTest.java:42)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[testng] at java.lang.Thread.run(Thread.java:619)
[testng] Caused by: org.dbunit.dataset.DataSetException: java.net.MalformedURLException
[testng] at org.dbunit.dataset.xml.FlatXmlProducer.produce(FlatXmlProducer.java:169)
[testng] at org.dbunit.dataset.CachedDataSet.<init>(CachedDataSet.java:71)
[testng] at org.dbunit.dataset.xml.FlatXmlDataSet.<init>(FlatXmlDataSet.java:200)
[testng] at org.dbunit.dataset.xml.FlatXmlDataSet.<init>(FlatXmlDataSet.java:187)
[testng] at org.jboss.seam.mock.AbstractDBUnitSeamTest$DataSetOperation.<init>(AbstractDBUnitSeamTest.java:226)
[testng] ... 19 more
[testng] ... Removed 11 stack frames
[testng] FAILED CONFIGURATION: @AfterMethod end
[testng] java.lang.NullPointerException
[testng] at org.jboss.seam.servlet.ServletSessionMap.get(ServletSessionMap.java:54)
[testng] at org.jboss.seam.contexts.BasicContext.get(BasicContext.java:49)
[testng] at org.jboss.seam.Component.getInstance(Component.java:1926)
[testng] at org.jboss.seam.Component.getInstance(Component.java:1921)
[testng] at org.jboss.seam.Component.getInstance(Component.java:1894)
[testng] at org.jboss.seam.Component.getInstance(Component.java:1889)
[testng] at org.jboss.seam.core.ConversationEntries.instance(ConversationEntries.java:94)
[testng] at org.jboss.seam.contexts.Lifecycle.endSession(Lifecycle.java:236)
[testng] at org.jboss.seam.contexts.ServletLifecycle.endSession(ServletLifecycle.java:146)
[testng] at org.jboss.seam.mock.AbstractSeamTest.end(AbstractSeamTest.java:904)
[testng] at org.jboss.seam.mock.SeamTest.end(SeamTest.java:37)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[testng] at java.lang.Thread.run(Thread.java:619)
[testng] ... Removed 13 stack frames
[testng] SKIPPED CONFIGURATION: @BeforeClass setDatasourceJndiName
[testng] SKIPPED CONFIGURATION: @BeforeMethod begin
[testng] SKIPPED CONFIGURATION: @AfterMethod end
[testng] SKIPPED CONFIGURATION: @AfterClass cleanupClass
[testng] SKIPPED CONFIGURATION: @AfterClass cleanupClass
[testng] SKIPPED CONFIGURATION: @AfterTest close
[testng] PASSED: test_user_with_noarg_facesrequest_constructor
[testng] PASSED: unitTestCrudUsingEntityHome
[testng] FAILED: test_using_seamtest_and_entitymanager
[testng] java.lang.AssertionError
[testng] at dk.mathmagicians.runtest.test.EntityManagerPersistenceTest.test_using_seamtest_and_entitymanager(EntityManagerPersistenceTest.java:26)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
[testng] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
[testng] at java.lang.Thread.run(Thread.java:619)
[testng] ... Removed 11 stack frames
[testng] SKIPPED: test_user_crud_using_unitdb
[testng] ===============================================
[testng] Various Tests
[testng] Tests run: 4, Failures: 1, Skips: 1
[testng] Configuration Failures: 2, Skips: 6
[testng] ===============================================
`
+++ My configuration
The TestNG suite:
`
suite name="TestingTestFramework" verbose="2" parallel="true">
<parameter name="datasourceJndiName" value="java:/runtestDatasource" />
<parameter name="database" value="HSQL" />
<parameter name="binaryDir" value="" />
<test name="Various Tests">
<classes>
<class name="dk.mathmagicians.runtest.test.UnitDBPersistenceTest" />
<class name="dk.mathmagicians.runtest.test.EntityManagerPersistenceTest" />
<class name="dk.mathmagicians.runtest.test.UserTest" />
<class name="dk.mathmagicians.runtest.test.UserUiTest" />
</classes>
</test>
</suite>
`
The persitence-test.xml - I tried some of the advices from forum, but no success ...
`
<persistence-unit name="runtest" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.cache.use_second_level_cache"
value="false" />
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/runtestEntityManagerFactory" />
<property name="hibernate.transaction.flush_before_completion"
value="true" />
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup" />
</properties>
</persistence-unit>
</persistence>
`
The User, UserBean and user.xhtml are trivial, autogenerated by seam.
Its clearly a configuration issue - can anybody help out?
Agata