Using embedded-jboss for unit testing

You can read and download the embedded-jboss from here: http://wiki.jboss.org/wiki/EmbeddedJBoss.
Using the embedded-jboss could contribute to the benefits that we can get the core functionalities of jboss from a very short deployment time(4~5s) for our unit testing.
Basing on that, we can obtain the resources of application storage such as hibernate sessions as same as the way in the web application, even, we can use the very same config files(in web application) of the storage persistence without any modification on them like *.cfg.xml and *-ds.xml
 
All we should do to make it work like this:
1. Add all jar files in "%Project%\embedded-jboss\lib" in your classpath.
2. Add all things under the directory "%Project%\embedded-jboss\bootstrap\" in your classpath too. I suggest that you can set the folder bootstrap as a source root folder in your ide.
3. Add the resource files in your classpath too, such as *.cfg.xml, *ds.xml, etc.
4. Create a file named persistence.xml under "META-INF\", also this folder should be added in your classpath.
5. Write a unit test class;
All done! You can use this sessions for you testing now.
 
PS:
1. I use EntityManager from Hibernate persistence in unit tests, it is defined in META-INF\persistence.xml like this:
<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="EntityManagerFactory1">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:/DS1</jta-data-source>
    <properties>
        <property name="jboss.entity.manager.factory.jndi.name"
                  value="java:/EntityManagerFactories/EntityManagerFactory1"/>
        <property name="hibernate.ejb.cfgfile" value="foo1.cfg.xml"/>
    </properties>
</persistence-unit>

<persistence-unit name="EntityManagerFactory2">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:/DS2</jta-data-source>
    <properties>
        <property name="jboss.entity.manager.factory.jndi.name"
                  value="java:/EntityManagerFactories/EntityManagerFactory2"/>
        <property name="hibernate.ejb.cfgfile" value="foo2.cfg.xml"/>
    </properties>
</persistence-unit>

...

</persistence>
  
 
2. Start embedded-jboss is very simply like this:
Bootstrap.getInstance().bootstrap();
Bootstrap.getInstance().deployResourceBase("foo-ds.xml");
Your datasources(java:/DS1 and java:/DS2) should be defined in the file foo-ds.xml following the template of Jboss.
 
Shutdown embedded-jboss 
Bootstrap.getInstance().shutdown();
  
After depolying embedded-jboss, you can get EntityFactory like this:
(HibernateEntityManagerFactory)Persistence.createEntityManagerFactor("EntityManagerFactory1");
(HibernateEntityManagerFactory)Persistence.createEntityManagerFactor("EntityManagerFactory2");
    ...
  
Then you can get hibernate session using these EntityManagerFactories.
 
3. TestNG is a little bit different from JUnit, but it's more easier to be used especially when you are testing a group of tests(it is called TestSuit in JUnit). Here is an example:
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.jboss.embedded.Bootstrap;
import org.jboss.deployers.spi.DeploymentException;

import javax.persistence.Persistence;

public class TestDeployer {
    static boolean isRunning = false;

    static HibernateEntityManagerFactory entityManagerFactory1;
    static HibernateEntityManagerFactory entityManagerFactory2;

    static void deploy() throws DeploymentException {
        Bootstrap.getInstance().bootstrap();
        Bootstrap.getInstance().deployResourceBase("foo-ds.xml");
        entityManagerFactory1= (HibernateEntityManagerFactory) Persistence.createEntityManagerFactory("EntityManagerFactory1");
        entityManagerFactory2= (HibernateEntityManagerFactory) Persistence.createEntityManagerFactory("EntityManagerFactory2");
    }

    static void unDeploy() throws DeploymentException {
        try {
            entityManagerFactory1.close();
            entityManagerFactory2.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        Bootstrap.getInstance().shutdown();
    }

}
 
import org.hibernate.Session;
import org.jboss.deployers.spi.DeploymentException;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;

/**
 * A simply test base class using TestNG
 * Our unit tests should be grouped by given names such as "beans", "entites", etc.
 * We can run a group of unit tests which belong the same group.
 * The running of a group can invoke a prepared method one time before the first test in it, such as the method "setUp" here.
 * The running of a group can invoke a finished method one time after all of the tests in it, such as the method "destroy" here.
 * The running of a group can invoke a method several times after each class in which group finishing all of its test methods, such as the method "closeSessions" here.
 */
public class TestBase {
    private Session session1;
    private Session session2;

    @BeforeGroups(groups = {"beans", "entities"})
    public void setUp() throws DeploymentException {
        TestDeployer.deploy();
    }

    @AfterGroups(groups = {"beans", "entities"})
    public void destroy() throws DeploymentException {
        TestDeployer.unDeploy();
    }

    @AfterClass(dependsOnGroups = {"beans", "entities"})
    public void closeSessions() {
        if (this.session1!= null)
            this.session1.close();
        if (this.session2!= null)
            this.session2.close();
    }

    protected Session getSession1() {
        if (this.session1== null || !this.session1.isOpen()) {
            this.session1= TestDeployer.entityManagerFactory1.getSessionFactory().openSession();
        }
        return this.session1;
    }

    protected Session getSession2() {
        if (this.session2== null || !this.session2.isOpen()) {
            this.session2= TestDeployer.entityManagerFactory2.getSessionFactory().openSession();
        }
        return this.session1;
    }
}
 
 
 
4.There are something records about the changes I made on embedded-jboss
   1). The embedded-jboss supports these features:
        
JNDI (remoteable) 
JCA 
-ds.xml files (connection pooling) 
JBoss Security 
(removed)EJB 3.0 (remoteable) 
(removed)JBoss Messaging 
(removed)JMX mbeans (-service.xml files) 
(removed)MC beans (-beans.xml files) 
(removed)JBoss TS
 
   2). I removed the features marked by "(removed)" above, for one thing, to speed up embedded-jboss on deploying, for another, there aresome errors after opening all features, they might be related with Seam and the Ejb feature is too complex for me to figure these errors out. But it is necessary to make clear about it because I can do unit test on features of Seam since I can't do it now!

   3). My changs on embedded-jboss(current version is beta3):   
a. Removed these files under "bootstrap\deploy":  all files except "jboss-local-jdbc.rar" 
b. Removed these files under "bootstrap\deployers": all files except "jca-deployers-beans.xml" and "security-deployer-beans.xml" 
c. Added file "standardjbosscmp-jdbc.xml"(getting from jboss-4.2.0.GA) into "bootstrap" 
d. Modified file "bootstrap\conf\jboss-service.xml", added these codes into the last:
<mbean code="org.jboss.ejb.plugins.cmp.jdbc.metadata.MetaDataLibrary" name="jboss.jdbc:service=metadata"/>
The -ds.xml file could take effect only after doing item c and d.     
 
5. At present, I just have taken these features: JNDI, JCA, DS file supporting and Security from embedded jboss, after all, they are same as in web application actually. 
     
6. What I have recorded here are just some tips, you should get details from official documents.      
   
7. 公司的Wiki只让发布英文的,所以就直接粘过来了,见谅。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值