13

我想要一个 JUnit(或其他)系统,可以在模拟环境中测试企业 bean,以便在本地注入所有资源/bean 等。企业 bean 不必完成此操作。应支持各种注入。

  • 我想为此提供一个 maven 插件,以便可以从 maven 构建运行测试。
  • 在单元测试期间不需要事务,这需要一个完整的容器。

你知道这样的maven插件或者测试框架吗?有经验吗?

4

2 回答 2

12

不一定是最简单的方法,但我设法使用 JBoss 的可嵌入 EJB3.0 容器来完成这项工作,并在Java Persistence with Hibernate的主要帮助下

首先,我不知道 maven 插件/依赖项,所以我必须在本地安装自己的:

(1)jboss-EJB-3.0_Embeddable_ALPHA_9.zip从下载中下载

(2) 这个 zipfile 包含两个重要的 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>

(6) 我还需要为HSQLDBSLF4J添加依赖项

conf(7)你需要将zipfile所在目录下的一些文件复制到src/main/resources你的项目目录下:

  • default.persistence.properties
  • ejb3-interceptors-aop.xml
  • embedded-jboss-beans.xml
  • jndi.properties

(8) 我在以下位置创建了自己的文件beans.xmlpersistence.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) 和 Message 实体类,如:

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.

}

可以说,在这种方法中存在许多绊脚石。

尤其是与依赖顺序有关。

祝你好运!!

于 2009-02-16T12:21:20.853 回答
4

我必须警告 JBoss 嵌入式是一团糟。你不需要相信我的话。亲自查看论坛。它是所有可能的方法。现在事情可能对你有用,但谁知道还有什么错误在等着你……假设你的项目会持续很长时间……那是有风险的。

你可以试试 OpenEJB。它在某些方面(在灵活性方面)受到限制,但它非常易于使用并且完全符合规范。有一些链接,例如thisthis。下载并试一试。顺便说一句,OpenEJB 通过阅读 JBoss 嵌入式论坛的帖子引起了我的注意……愤怒的用户指出了替代方案。

就个人而言,我决定为我的项目创建一种模拟容器,让我可以测试几乎任何我需要的东西。对于持久性,我使用 Hibernate Entity Manager + HSQL。我花了一周的时间来实施,但我的团队(到目前为止 2 个)对此非常满意。如果可能的话,我会把它开源。

最后一个选项是ejb3unit

于 2009-03-11T04:27:35.573 回答