Java开发网 Java开发网
注册 | 登录 | 帮助 | 搜索 | 排行榜 | 发帖统计  

您没有登录

» Java开发网 » 技术文章库  

按打印兼容模式打印这个话题 打印话题    把这个话题寄给朋友 寄给朋友    该主题的所有更新都将Email到你的邮箱 订阅主题
flat modethreaded modego to previous topicgo to next topicgo to back
作者 【原创】使用MockEJB测试SessionBean及数据库应用
jiangbo99





发贴: 2
积分: 2
于 2005-01-21 15:02 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
J2EE应用中对于EJB的单元测试是很麻烦的,需要写完EJB后再打包、部署、测试出问题后再次修改、打包、部署。。。。。而打包、部署的时间往往是最浪费时间的,MockEJB可以帮助我们省略这2步,编译完成后即可运行,调试方法跟普通的javabean类似。

MockEJB其实模拟了一个mini J2EE容器,对ejb的mock操作都在该虚拟容器内部执行,能够满足绝大部分的EJB功能测试。

为了更方便的使用MockEJB,我们可以对其中常用的绑定、部署功能进行封装。


import org.mockejb.OptionalCactusTestCase;
import org.mockejb.MockContainer;
import org.mockejb.SessionBeanDescriptor;
import org.mockejb.jndi.MockContextFactory;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.StringTokenizer;

import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.SessionFactory;
import com.mockrunner.mock.ejb.MockUserTransaction;
import junit.framework.TestCase;

/**
* 使用MockEJB做测试时的辅助类,
* 封装了常用的deploy和bind方法。
* 用自己的测试类继承该抽象类。
* <p/>
* @author lucene
* @version 1.0 2004-12-15 10:26:33
*/
public abstract class AbstractMockEJBTest extends TestCase {

private Context context;
private MockContainer mockContainer;

/**
* 初始化上下文环境。
*/
protected void setUp() throws Exception {
MockContextFactory.setAsInitial();
context = new InitialContext();
mockContainer = new MockContainer(context);
}

/**
* 取得上下文环境
*
* @return 上下文环境
*/
protected Context getContext() {
return context;
}

/**
* 把指定的SessionBean部署到Mock的容器环境中。
*
* @param jndi JNDI名称
* @param home 主接口
* @param remote 远程接口
* @param bean 实现类
* @throws Exception
*/
public void deploySessionBean(String jndi, Class home, Class remote, Class bean) throws Exception {
SessionBeanDescriptor descriptor =
new SessionBeanDescriptor(jndi, home, remote, bean);
mockContainer.deploy(descriptor);
}

/**
* 绑定数据源到上下文环境,这里默认提供的是Oracle的数据源,
* 如果是MySQL,那么数据源就使用:
* <code>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</code>
* 如果使用其他的数据库连结池来获取数据源则无需调用该方法。
*
* @param jndi JNDI名称
* @param url JDBC URL
* @param user 用户名
* @param password 密码
* @throws Exception
*/
public void bindDataSource(String jndi, String url, String user, String password) throws Exception {
oracle.jdbc.pool.OracleDataSource ds = new oracle.jdbc.pool.OracleDataSource();
ds.setURL(url);
if(user != null) ds.setUser(user);
if(password != null) ds.setPassword(password);
context.rebind(jndi, ds);
}

/**
* 绑定<code>SessionFactory</code>到指定的JNDI名称
* @param jndi JNDI名称
* @param cfgFiles 配置文件,中间用半角逗号隔开
* @throws Exception
*/
public void bindHibernate(String jndi, String cfgFiles) throws Exception {
StringTokenizer st = new StringTokenizer(cfgFiles, ",");
Configuration cfg = new Configuration();
while(st.hasMoreTokens()) {
String cfgFile = st.nextToken().trim();
cfg.configure(cfgFile);
}
SessionFactory sf = cfg.buildSessionFactory();
context.rebind(jndi, sf);
}

/**
* 绑定事务处理到JNDI。
*
* @param trans MockEJB的<code>MockUserTransaction</code>类
* @throws Exception
*/
public void bindTransaction(MockUserTransaction trans) throws Exception {
if(trans == null) trans = new MockUserTransaction();
context.rebind("javax.transaction.UserTransaction", trans);
}

public void tearDown() {
MockContextFactory.revertSetAsInitial();
}

}


接下来的单元测试工作就很轻松啦,例如:

public class XXXUnitTest extends AbstractMockEJBTest {
private ResourceServiceManager resServiceManager;
private ResourceServiceManagerHome resServiceManagerHome;

public void setUp() throws Exception {
super.setUp();
super.deploySessionBean(ResourceServiceManagerHome.JNDI_NAME,
ResourceServiceManagerHome.class, ResourceServiceManager.class, ResourceServiceManagerBean.class);
super.deploySessionBean(ResourceStockManagerHome.JNDI_NAME,
ResourceStockManagerHome.class, ResourceStockManager.class, ResourceStockManagerBean.class);
super.bindDataSource("xxxx3ds", "jdbc:oracle:thin:@dbserver:1521:orcl", "user", "pass");
super.bindHibernate("hibernate/session_factory", "/xxx.cfg.xml, /xxx1.cfg.xml, /xxx2.cfg.xml");
super.bindTransaction(mockTransaction);
resServiceManagerHome = (ResourceServiceManagerHome) super.getContext().lookup(ResourceServiceManagerHome.JNDI_NAME);
resServiceManager = resServiceManagerHome.create();
}
public void testXXXXXX() throws Exception {
Collection result = resServiceManager.getXXXXXX();
assertNotNull(result);
}
}

修改ResourceServiceManagerBean后不需要重新打包、部署EJB,直接编译,然后再次运行单元测试就能看到更新后的结果了。


floater edited on 2005-01-21 23:55

作者 Re:【原创】使用MockEJB测试SessionBean及数据库应用 [Re:jiangbo99]
floater

Java Jedi

总版主


发贴: 3233
积分: 421
于 2005-01-22 00:04 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
I get rid of the smiling face.

Is there any reason why you are using oracle.jdbc.pool.OracleDataSource instead of java's DataSource?



"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."
- Martin Fowler, Refactoring - Improving the Design of Existing Code

flat modethreaded modego to previous topicgo to next topicgo to back
  已读帖子
  新的帖子
  被删除的帖子
Jump to the top of page

   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923