9 Replies Latest reply on Jan 8, 2008 2:22 AM by jagin

    Uni testing and datasource problem

      Hi to all,

      I generate simple application with seam-gen. I didn't touch any existing code. I add simple UserDaoSeam class wich I want to test.
      I have some problem with simple unit testing. I want to do something like in the Seam Reference book on page 293-294.
      The code of the test is like this:

      public class UserDaoTest extends SeamTest {
      
       private EntityManagerFactory emf;
      
       public EntityManagerFactory getEntityManagerFactory() {
       return emf;
       }
      
       @BeforeClass
       public void init() {
       emf = Persistence.createEntityManagerFactory("ezapp");
       }
      
       @AfterClass
       public void destroy() {
       emf.close();
       }
      
       @Test
       public void testFindByUsername() {
       EntityManager em = emf.createEntityManager();
       em.getTransaction().begin();
      
       UserDaoSeam userDao = new UserDaoSeam();
       userDao.setEntityManager(em);
      
       User user = userDao.findByUsername("jkowalski");
      
       assert user != null;
      
       em.getTransaction().rollback();
       em.close();
       }
      }
      


      after ant test i get

      D:\dev\ezapp>ant test
      Buildfile: build.xml
      
      compiletest:
      
      copytestclasses:
      
      buildtest:
       [copy] Copying 1 file to D:\dev\ezapp\test-build\META-INF
       [copy] Copying 1 file to D:\dev\ezapp\test-build
      
      test:
       [testng] [Parser] Running:
       [testng] D:\dev\ezapp\test-build\PersistenceTest.xml
       [testng]
       [testng] FATAL [org.hibernate.connection.DatasourceConnectionProvider] Could not find datasource: java:/DefaultDS
       [testng] java.lang.RuntimeException: PROVIDER_URL not provided in jndi.properties. Automatic discovery not implemented yet.
       [testng] at org.jboss.naming.JBossRemotingContextFactory.getInitialContext(JBossRemotingContextFactory.java:158)
       [testng] at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
       [testng] at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:247)
       [testng] at javax.naming.InitialContext.init(InitialContext.java:223)
       [testng] at javax.naming.InitialContext.<init>(InitialContext.java:175)
       [testng] at org.hibernate.util.NamingHelper.getInitialContext(NamingHelper.java:28)
       [testng] at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:52)
       [testng] at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
       [testng] at org.hibernate.ejb.InjectionSettingsFactory.createConnectionProvider(InjectionSettingsFactory.java:29)
       [testng] at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:62)
       [testng] at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)
       [testng] at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
       [testng] at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:918)
       [testng] at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:656)
       [testng] at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:121)
       [testng] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:52)
       [testng] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:34)
       [testng] at pl.unizeto.ezapp.persistence.UserDaoTest.init(UserDaoTest.java:24)
       [testng] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       [testng] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       [testng] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       [testng] at java.lang.reflect.Method.invoke(Method.java:585)
       [testng] at org.testng.internal.MethodHelper.invokeMethod(MethodHelper.java:604)
       [testng] at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:394)
       [testng] at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
       [testng] at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:79)
       [testng] at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:165)
       [testng] at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:103)
       [testng] at org.testng.TestRunner.runWorkers(TestRunner.java:678)
       [testng] at org.testng.TestRunner.privateRun(TestRunner.java:624)
       [testng] at org.testng.TestRunner.run(TestRunner.java:495)
       [testng] at org.testng.SuiteRunner.runTest(SuiteRunner.java:300)
       [testng] at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:295)
       [testng] at org.testng.SuiteRunner.privateRun(SuiteRunner.java:275)
       [testng] at org.testng.SuiteRunner.run(SuiteRunner.java:190)
       [testng] at org.testng.TestNG.createAndRunSuiteRunners(TestNG.java:792)
       [testng] at org.testng.TestNG.runSuitesLocally(TestNG.java:765)
       [testng] at org.testng.TestNG.run(TestNG.java:699)
       [testng] at org.testng.TestNG.privateMain(TestNG.java:824)
       [testng] at org.testng.TestNG.main(TestNG.java:802)
       [testng] FAILED CONFIGURATION: @BeforeClass init
       [testng] javax.persistence.PersistenceException: org.hibernate.HibernateException: Could not find datasource
       [testng] at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:663)
       [testng] at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:121)
       [testng] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:52)
       [testng] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:34)
       [testng] at pl.unizeto.ezapp.persistence.UserDaoTest.init(UserDaoTest.java:24)
       [testng] Caused by: org.hibernate.HibernateException: Could not find datasource
       [testng] at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:56)
       [testng] at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
       [testng] at org.hibernate.ejb.InjectionSettingsFactory.createConnectionProvider(InjectionSettingsFactory.java:29)
       [testng] at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:62)
       [testng] at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2009)
       [testng] at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1292)
       [testng] at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:918)
       [testng] at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:656)
       [testng] ... 26 more
       [testng] Caused by: java.lang.RuntimeException: PROVIDER_URL not provided in jndi.properties. Automatic discovery not implemented yet.
       [testng] at org.jboss.naming.JBossRemotingContextFactory.getInitialContext(JBossRemotingContextFactory.java:158)
       [testng] at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
       [testng] at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:247)
       [testng] at javax.naming.InitialContext.init(InitialContext.java:223)
       [testng] at javax.naming.InitialContext.<init>(InitialContext.java:175)
       [testng] at org.hibernate.util.NamingHelper.getInitialContext(NamingHelper.java:28)
       [testng] at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:52)
       [testng] ... 33 more
       [testng] ... Removed 22 stack frames
       [testng] FAILED CONFIGURATION: @BeforeMethod begin
       [testng] java.lang.IllegalStateException: Attempted to invoke a Seam component outside the an initialized application
       [testng] at org.jboss.seam.contexts.Lifecycle.getApplication(Lifecycle.java:36)
       [testng] at org.jboss.seam.contexts.Lifecycle.beginSession(Lifecycle.java:173)
       [testng] at org.jboss.seam.contexts.ServletLifecycle.beginSession(ServletLifecycle.java:124)
       [testng] at org.jboss.seam.mock.BaseSeamTest.begin(BaseSeamTest.java:918)
       [testng] at org.jboss.seam.mock.SeamTest.begin(SeamTest.java:28)
       [testng] ... Removed 24 stack frames
       [testng] SKIPPED CONFIGURATION: @AfterMethod end
       [testng] SKIPPED CONFIGURATION: @AfterClass destroy
       [testng] SKIPPED CONFIGURATION: @AfterClass cleanup
       [testng] SKIPPED: testFindByUsername
       [testng]
       [testng] ===============================================
       [testng] ezApp
       [testng] Tests run: 1, Failures: 0, Skips: 1
       [testng] Configuration Failures: 2, Skips: 3
       [testng] ===============================================
       [testng]
       [testng]
       [testng] ===============================================
       [testng] ezApp
       [testng] Total tests run: 1, Failures: 0, Skips: 1
       [testng] Configuration Failures: 2, Skips: 3
       [testng] ===============================================
       [testng]
      
      BUILD SUCCESSFUL
      Total time: 2 seconds
      


      the persistence-test.xml is seam-gen generated without any change

      <?xml version="1.0" encoding="UTF-8"?>
      <!-- Persistence deployment descriptor for tests -->
      <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="ezapp">
       <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.show_sql" value="true"/>
       <property name="hibernate.cache.use_second_level_cache" value="false"/>
       <property name="jboss.entity.manager.factory.jndi.name" value="java:/ezappEntityManagerFactory"/>
       </properties>
       </persistence-unit>
      
      </persistence>
      


      Why i'm getting Could not find datasource: java:/DefaultDS error? Am I missing something. I read all reference book, diged forum and googled very deep and didn't find any solution. What's wrong?

      I found that DefaultDS is defined in bootstrap/deploy/hsqldb-ds.xml. So I made this file errorous but i got the same error. I looks like this file is not read in the embedded environment.

      I try this wit Seam 2.0.0.GA and 2.0.1.CR1

      Any help or working unit test example will be very weelcome.

      I'm a newbee in seam matter so please be kind :] ( i'm trying to switch from appfuse framework and like the Seam concept very much).

      Jarek


        • 1. Re: Uni testing and datasource problem

          Please help me with the problem !! I've been strugling with this for two days (all weekend) and have no idea whats wrong. I'm new to JBoss Seam but not new to java web development but I have no idea what's wrong. It drives me crazy!

          Can anybody try to generate any simple application with seam-gen and put to src/test test MyTest.java like this:

          import javax.persistence.EntityManager;
          import javax.persistence.EntityManagerFactory;
          import javax.persistence.Persistence;
          
          import org.jboss.seam.mock.SeamTest;
          import org.testng.annotations.AfterClass;
          import org.testng.annotations.BeforeClass;
          import org.testng.annotations.Test;
          
          public class MyTest {
          
           private EntityManagerFactory emf;
          
           public EntityManagerFactory getEntityManagerFactory() {
           return emf;
           }
          
           @BeforeClass
           public void init() {
           emf = Persistence.createEntityManagerFactory("project_name");
           }
          
           @AfterClass
           public void destroy() {
           emf.close();
           }
          
           @Test
           public void testFindByUsername() {
           EntityManager em = emf.createEntityManager();
           em.getTransaction().begin();
          
           //...
          
           em.getTransaction().rollback();
           em.close();
           }
          }
          


          as a project_name put your name of the project.

          and MyTest.xml like this:

          <!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
          
          <suite name="My Test" verbose="2" parallel="false">
          
           <test name="My Test">
           <classes>
           <class name="MyTest"/>
           </classes>
           </test>
          
          </suite>
          


          next try to ant test and tell me if the test goes with no error?

          For me it looks that the persistant.xml file is read before any initialization by Jboss Embedded. I check that application.xml, components.xml, ejb-jar.xml, jboss-app.xml are not read.

          Please help me. I'm stucked.

          Regards

          Jarek


          • 2. Re: Uni testing and datasource problem

            OK, I resolved this mystery.

            The unit test should look like this:

            public class MyTest extends SeamTest {
            
             private EntityManagerFactory emf;
            
             @Test
             public void testFindByUsername() {
             emf = Persistence.createEntityManagerFactory("ezapp");
            
             EntityManager em = emf.createEntityManager();
             em.getTransaction().begin();
            
             //...
            
             em.getTransaction().rollback();
             em.close();
            
             emf.close();
             }
            
            }
            


            The problem was with

             @BeforeClass
             public void init() {
             emf = Persistence.createEntityManagerFactory("project_name");
             }
            


            It seems that createEntityManagerFactory is called before JBoss Embedded is initialized. Is it bug? In the reference book there is an example of unit test with BeforeClass.

            Regards

            Jarek

            • 3. Re: Uni testing and datasource problem

              The last working example is not very good because for every @Test method we have to createEntityManagerFactory. I don't think it's a good idea.
              So i found a better solution:

              public class MyTest extends SeamTest {
               private EntityManagerFactory emf;
              
               @Override
               @BeforeClass
               public void init() throws Exception {
               super.init();
               emf = Persistence.createEntityManagerFactory("ezapp");
               }
              
               @Override
               @AfterClass
               public void cleanup() throws Exception {
               emf.close();
               super.cleanup();
               }
              
               @Test
               public void testFindByUsername() {
               EntityManager em = emf.createEntityManager();
               em.getTransaction().begin();
              
               em.getTransaction().rollback();
               em.close();
               }
              }
              


              First we have to extend SeamTest even if we are not going to use it's functionality in our unit test. But we need to initialize embedded container which is started in SeamTest.init(). So we override this method, call super.init() to initialize container and next we create our EntityManagerFactory. We close EntityManagerFactory in overrided cleanup() method.


              Regards

              Jarek


              • 4. Re: Uni testing and datasource problem
                pmuir

                If you are using Embedded JBoss/SeamTest you don't need to create the entity manager yourself. If you are using an SMPC

                getInstance("entityManager");


                otherwise do a JNDI lookup for it.

                • 5. Re: Uni testing and datasource problem

                   

                  "pete.muir@jboss.org" wrote:
                  If you are using Embedded JBoss/SeamTest you don't need to create the entity manager yourself. If you are using an SMPC

                  getInstance("entityManager");


                  otherwise do a JNDI lookup for it.


                  I tried this:

                   @Test
                   public void testFindByUsername() {
                   EntityManager em = (EntityManager)getInstance("entityManager");
                   em.getTransaction().begin();
                  
                   UserDaoSeam userDao = new UserDaoSeam();
                   userDao.setEntityManager(em);
                  
                   User user = userDao.findByUsername("jkowalski");
                  
                   assert user != null;
                  
                   em.getTransaction().rollback();
                   em.close();
                   }
                  


                  but got

                   [testng] FAILED: testFindByUsername
                   [testng] java.lang.IllegalStateException: No application context active
                   [testng] at org.jboss.seam.Component.forName(Component.java:1799)
                   [testng] at org.jboss.seam.Component.getInstance(Component.java:1849)
                   [testng] at org.jboss.seam.Component.getInstance(Component.java:1832)
                   [testng] at org.jboss.seam.Component.getInstance(Component.java:1826)
                   [testng] at org.jboss.seam.mock.BaseSeamTest.getInstance(BaseSeamTest.java:104)
                   [testng] at pl.unizeto.ezapp.persistence.UserDaoTest.testFindByUsername(UserDaoTest.java:59)
                   [testng] ... Removed 22 stack frames
                  


                  • 6. Re: Uni testing and datasource problem
                    pmuir

                    You need to be in a FacesRequest for this to work.

                    • 7. Re: Uni testing and datasource problem

                       

                      "pete.muir@jboss.org" wrote:
                      You need to be in a FacesRequest for this to work.


                      But I want to do a simple unit testing.

                      • 8. Re: Uni testing and datasource problem
                        pmuir
                        • 9. Re: Uni testing and datasource problem

                          At the first time I tried to do a simple unit testing without SeamTest (the same test as in my first post but without 'extends SeamTest' takeoff on JBoss Seam 2.0.0.GA Reference book page 293-294). But i got error Could not find datasource: java:/DefaultDS because the line emf = Persistence.createEntityManagerFactory("ezapp"); was called before the JBoss Embedded was initialized. Somewhere on the forum i have found that @BeforeClass in testng test is called before initializing the JBoss Embeded.
                          So i do the trick with extending SeamTest and overriding init and cleanup as in my 4-th post.

                          Lastly i have noticed that the error is triggered when this unit test is the first test in the *Test.xml package. If there is any test before which initialize embedded environment everything is ok.

                          Did you try to do a simple test like discribed in my 2-nd post or as in http://docs.jboss.org/seam/2.0.1.CR1/reference/en/html/testing.html#d0e19771 with clean app generated by seam-gen? It won't go because of @BeforeClass and the problem above.

                          As I said i'm new in JBoss Seam and there is a lot to learn for me so i'm trying to solve some problems with mist over my eyes.

                          Regards

                          Jarek