4 Replies Latest reply on May 1, 2009 1:19 AM by mikkus70

    SeamTest and UnitDBSeamTest configuration issue - doesn't work out of the box

    themathmagician
      I 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
        • 1. Re: SeamTest and UnitDBSeamTest configuration issue - doesn't work out of the box
          jnusaira

          Dont put any of the entity manager items in the before or after ... i used to get strange errors when i tried to do that stuff as well.


          Also

          • 2. Re: SeamTest and UnitDBSeamTest configuration issue - doesn't work out of the box
            mikkus70

            AbstractDBUnitSeamTest uses getResourceAsStream() to retrieve the dataset file, so you'll need to put this file within a source folder in the test project.


            I usually do the following:



            1. create a testdata package under test-src.

            2. create two more packages under it: testdata.sets for datasets and testdata.binaries for binaries (even if you don't use binaries in your tests, you still need to provide an existing binaries location).

            3. configure the binaryDir parameter of testng.xml to point to testdata/binaries/.

            4. when adding the dataset in your beforeTestOperations method, refer to xml datasets as testdata/sets/myset.xml.



            This should get you going.

            • 3. Re: SeamTest and UnitDBSeamTest configuration issue - doesn't work out of the box
              zmicer

              Just a quick note: data source name in my testng.xml and persistence.xml are the same. May be this causes some problems?



              <suite name="Quartz Example" verbose="2" parallel="false">
                   <test name="Quartz Example">
                    
                      <parameter name="datasourceJndiName" value="*java:/DefaultDS*"/>
                      <parameter name="database" value="HSQL" />
                      <parameter name="binaryDir" value="" />
                      
                        <classes>
                        </classes>
                   </test>
              </suite> 





              <?xml version="1.0" encoding="UTF-8"?>
              <persistence xmlns="http://java.sun.com/xml/ns/persistence" 
                           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                           xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
                           version="1.0">
                 <persistence-unit name="bookingDatabase" transaction-type="RESOURCE_LOCAL">
                    <provider>org.hibernate.ejb.HibernatePersistence</provider>
                    <non-jta-data-source>*java:/DefaultDS*</non-jta-data-source>
                    <properties>
                       <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
                       <property name="hibernate.show_sql" value="true"/>
                       <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider"/>
                       <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>
                       <!-- alternative
                       <property name="jboss.entity.manager.factory.jndi.name" 
                            value="java:/jpaBookingEntityManagerFactory"/>
                       -->
                    </properties>
                 </persistence-unit>
              </persistence>




              Kind regards,
              Dzmitry

              • 4. Re: SeamTest and UnitDBSeamTest configuration issue - doesn't work out of the box
                mikkus70

                No, I too have the datasource name identical in both testng.xml and persistence.xml and it works just fine. You don't specify your specific problem or report any exceptions, but it could be that your datasource transaction type is RESOURCE_LOCAL... it shouldn't (you're testing within the jboss container and are using JBossTransactionManagerLookup, which returns a JTA transaction).