在不部署组件的情况下对 EJB3 组件进行单元测试的最佳方法是什么
我希望有一个JUnit(或其他)系统,可以在模拟环境中测试企业Bean,以便所有资源/Bean等都在本地注入。企业 Bean 不应该必须完成此操作。应支持各种注射。
- 我希望为此提供一个maven插件,以便可以从maven构建中运行测试。
- 在单元测试期间不需要事务,这将需要一个完整的容器。
您知道这样的maven插件或测试框架吗?体验它?
我希望有一个JUnit(或其他)系统,可以在模拟环境中测试企业Bean,以便所有资源/Bean等都在本地注入。企业 Bean 不应该必须完成此操作。应支持各种注射。
您知道这样的maven插件或测试框架吗?体验它?
不一定是最简单的方法,但我设法使用JBoss的可嵌入EJB3.0容器来工作,并得到了Java Persistence with Hibernate的主要帮助。
首先,我不知道为此提供哪些 maven 插件/依赖项,因此我不得不在本地安装自己的插件/依赖项:
(1) 从下载下载jboss-EJB-3.0_Embeddable_ALPHA_9.zip
(2) 此 zip 文件包含两个重要的 JAR:
jboss-ejb3-all.jar
thirdparty-all.jar
(3) 将这些 JAR 安装到您的本地存储库中(使用您自己的首字母缩写而不是):nkl
mvn install:install-file \
-Dfile=jboss-ejb3-all.jar \
-DgroupId=nkl.jboss.embedded \
-DartifactId=jboss-ejb3-all \
-Dversion=3.0-alpha-9
mvn install:install-file \
-Dfile=thirdparty-all.jar \
-DgroupId=nkl.jboss.embedded \
-DartifactId=thirdparty-all \
-Dversion=3.0-alpha-9
(4) 如果一切顺利,您现在应该在本地存储库中有两个目录。
(5) 现在将以下依赖项添加到您的pom.xml
<dependency>
<groupId>nkl.jboss.embedded</groupId>
<artifactId>jboss-ejb3-all</artifactId>
<version>3.0-alpha-9</version>
</dependency>
<dependency>
<groupId>nkl.jboss.embedded</groupId>
<artifactId>thirdparty-all</artifactId>
<version>3.0-alpha-9</version>
</dependency>
(7)您需要将一些文件从zip文件的目录复制到项目的目录中:conf
src/main/resources
default.persistence.properties
ejb3-interceptors-aop.xml
embedded-jboss-beans.xml
jndi.properties
(8)我在以下位置创建了自己的文件:beans.xml
persistence.xml
src/main/resources/META-INF
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:jboss:bean-deployer bean-deployer_1_0.xsd" xmlns="urn:jboss:bean-deployer">
<bean name="messageDSBootstrap" class="org.jboss.resource.adapter.jdbc.local.LocalTxDataSource">
<property name="jndiName">java:/messageDS</property>
<property name="driverClass">org.hsqldb.jdbcDriver
</property>
<property name="connectionURL">jdbc:hsqldb:test</property>
<property name="minSize">0</property>
<property name="maxSize">10</property>
<property name="blockingTimeout">1000</property>
<property name="idleTimeout">30000</property>
<property name="transactionManager">
<inject bean="TransactionManager" />
</property>
<property name="cachedConnectionManager">
<inject bean="CachedConnectionManager" />
</property>
<property name="initialContextProperties">
<inject bean="InitialContextProperties" />
</property>
</bean>
<bean name="messageDS" class="java.lang.Object">
<constructor factoryMethod="getDatasource">
<factory bean="messageDSBootstrap" />
</constructor>
</bean>
</deployment>
<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="jpa">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:/messageDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
</persistence>
(9) 我使用此处的其他信息创建了一个如下所示的单元测试。
package org.nkl;
import java.io.File;
import javax.naming.InitialContext;
import org.jboss.ejb3.embedded.EJB3StandaloneBootstrap;
import org.jboss.ejb3.embedded.EJB3StandaloneDeployer;
import org.junit.Test;
import org.nkl.model.MessageHandler;
public class BasicTest {
@Test
public void testEjb() throws Exception {
EJB3StandaloneBootstrap.boot(null);
EJB3StandaloneBootstrap.deployXmlResource("META-INF/beans.xml");
EJB3StandaloneDeployer deployer = EJB3StandaloneBootstrap
.createDeployer();
deployer.getArchives().add(new File("target/classes").toURI().toURL());
deployer.create();
deployer.start();
InitialContext context = new InitialContext();
MessageHandler messageHandler = (MessageHandler) context
.lookup("MessageHandlerBean/local");
messageHandler.saveMessages();
messageHandler.showMessages();
EJB3StandaloneBootstrap.shutdown();
}
}
(10) 这使用一个简单的 SLSB,如下所示:
package org.nkl.ejb;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.nkl.model.Message;
import org.nkl.model.MessageHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Stateless
public class MessageHandlerBean implements MessageHandler {
@PersistenceContext
private EntityManager em;
Logger logger = LoggerFactory.getLogger(MessageHandlerBean.class);
public void saveMessages() {
logger.info("In saveMessages");
em.persist(new Message("Hello World"));
}
@SuppressWarnings("unchecked")
public void showMessages() {
logger.info("In showMessages");
List messages = em.createQuery(
"select m from Message m order by m.text asc").getResultList();
for (Object o : messages) {
logger.info(((Message) o).getText());
}
}
}
(11) 和一个消息实体类,如:
package org.nkl.model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "MESSAGES")
public class Message {
@Id
@GeneratedValue
@Column(name = "MESSAGE_ID")
private Long id;
@Column(name = "MESSAGE_TEXT")
private String text;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "NEXT_MESSAGE")
private Message nextMessage;
public Message(String text) {
this.text = text;
}
Message() {}
// setters/getters not shown.
}
让我们说,在这种方法的过程中,有许多绊脚石。
特别是与依赖关系的顺序有关。
祝你好运!!
我必须警告说,嵌入的JBoss是一团糟。你不需要相信我的话。亲自查看论坛。它通过一切可能的手段是阿尔法。事情现在可能对你有用,但谁知道什么错误仍然在那里等着......假设你的项目将存活很长时间。这是一种风险。
你可以试试 OpenEJB。它在某些方面(在灵活性方面)受到限制,但它确实易于使用并且完全符合规范。有一些链接,例如这个和这个。下载并试一试。顺便说一句,OpenEJB通过阅读JBoss嵌入式论坛的帖子引起了我的注意......来自愤怒的用户指出替代方案。
就个人而言,我决定为我的项目创建一种模拟容器,使我几乎可以测试我需要的任何内容。对于持久性,我使用Hibernate Entity Manager + HSQL。我花了一个星期来实施,但我的团队(到目前为止有2个)对此非常满意。如果可能的话,我会把它变成开源的。
最后一个选项是 ejb3unit。